Вложенный ресурс загружен не по порядку - PullRequest
1 голос
/ 13 октября 2011

У меня есть учебный класс и класс степа. У учебника есть много шагов, и каждый шаг принадлежит учебнику. У меня есть эта настройка в моих моделях и в файле маршрутов. В действии show в учебном классе все шаги, принадлежащие этому учебному пособию, также загружаются. Проблема в том, что после создания нескольких шагов 4-6 они выйдут из строя. Например, первый загруженный шаг - это шаг 7, но после этого шаги в порядке. Я использую postgresql для базы данных и включаю гем pg в свой gemfile. Модель учебника:

class Tutorial < ActiveRecord::Base
  attr_accessible :name, :summary, :permalink   
  has_many :steps

  validates :name, :presence => true,
               :length => { :maximum => 50 },
               :uniqueness => { :case_sensitive => false }  

  validates :summary, :presence => true,
          :length => { :maximum => 2000 }

  before_create :set_up_permalink

  def to_param
permalink
  end

  private

  def set_up_permalink
    permalink = self.name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
  self.permalink = permalink
end

Модель шага:

class Step < ActiveRecord::Base
  attr_accessible :tutorial_id, :body, :position
  belongs_to :tutorial

  validates :body, :presence => true

  before_create :assign_position

  private

  def assign_position
@tutorial = self.tutorial
@position = @tutorial.steps.size
    @position = @position + 1
    self.position = @position
  end
end

Маршруты:

resources :tutorials do
  resources :steps
end

def show
  @tutorial = Tutorial.find_by_permalink(params[:id])
  @steps = @tutorial.steps
  @next = @steps[0]
  @title = "#{@tutorial.name} - A Ruby on Rails tutorial"
  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => @tutorial }
  end
end

Учебное пособие по просмотру

<%= render :partial => @tutorial.steps %>

Ответы [ 2 ]

3 голосов
/ 13 октября 2011

Где вы устанавливаете заказ? Вы можете сделать это так:

@steps = @tutorial.steps.order('position')

Или даже лучше, поскольку я не могу вспомнить ни одного случая, когда бы вы хотели, чтобы шаги вышли из строя:

В вашей модели Step:

default_scope order('position')

Кроме того, вы можете определить порядок в определении ассоциации:

В вашей модели учебника:

has_many :steps, :order => 'position'

edit и, к черту, вот гораздо более краткий способ написать ваш assign_position метод:

  def assign_position
    self.position = tutorial.steps.size + 1
  end
0 голосов
/ 13 октября 2011

Ваша логика для назначения позиции ошибочна, если шаги могут быть произвольно добавлены и удалены.

например.

  • Я создаю учебник и 3 шага, с позициями [1,2,3].
  • Затем я удаляю шаг с позиции 2.
  • Теперь осталось 2 шага с позициями [1,3].
  • Позже я создаю еще один шаг, которому присваивается позиция 3.
  • Теперь есть три шага, но их позиции [1,3,3]. Это не правильно!

Есть несколько подходов, которые я бы рассмотрел, чтобы исправить ситуацию:

Первый путь

Вы можете сохранить свой код для назначения позиции новому шагу, но когда шаг удален из учебника, обновите позиции, чтобы убедиться, что они последовательны. Вот эскиз того, как это будет работать.

class Tutorial
  def rectify_step_positions
    # reassign positions so that all the steps form a sequence
    # E.g. step positions [1,3,4] become [1,2,3]
  end
end

class Step
  after_destroy :trigger_rectify_positions

  def trigger_rectify_positions
    tutorial.rectify_step_positions
  end
end

Второй способ

Когда вы создаете новый шаг, вы можете назначить его позицию на 1 больше максимальной позиции среди всех существующих шагов.

def assign_position
  self.position = tutorial.steps.order("position DESC").first.position + 1
end

Этот метод немного проще для реализации, чем первый. Конечно, теперь позиции не имеют такого большого значения, поскольку они не обязательно последовательны. Шаг с позицией 10 может быть вторым шагом учебника.

Заключение

Как только вы исправите свою проблему с позицией, вы можете просто заказать шаги. Брикер показал несколько способов сделать это. Лично мне нравится has_many :steps, :order => 'position'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...