before_filter или спасение для создания новой записи - PullRequest
2 голосов
/ 25 января 2010

У меня 2 модели

class Room < ActiveRecord::Base
  has_many :people
  accepts_nested_attributes_for :people, :reject_if => lambda { |a| a[:person_id].blank? }, :allow_destroy => true
end

class Person < ActiveRecord::Base
  belongs_to :room
end

В форме '/ rooms / new' у меня есть тег выбора, содержащий всех персонажей, и тег опции 'other', который позволяет пользователю динамически добавлять человека в тег выбора (новое имя).

Итак, когда я отправляю свою форму, у меня может быть человек с идентификатором = -1, которого нет в базе данных, и, конечно, я хочу создать нового человека с новым именем.

Мне интересно, как лучше всего этого добиться?

с 'before_filter' или 'спасением ActiveRecord :: RecordNotFound' или ...

спасибо за вашу помощь

Ответы [ 2 ]

2 голосов
/ 26 января 2010

Вам не нужно никакого специального кода. ActiveRecord уже включает логику для обработки этого случая.

Прочтите rdoc на http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/nested_attributes.rb#L328 или http://github.com/rails/rails/blob/master/activerecord/lib/active_record/nested_attributes.rb#L332 для подробностей. По сути, если хэш передается с ключом: id, атрибуты записи обновляются. Если запись не имеет ключа: id, создается новая запись. Если он имеет ключ: id и ключ: _destroy со значением true'ish, запись будет удалена.

Ниже приведена 2-3-стабильная отраслевая документация:

# Assigns the given attributes to the collection association.
#
# Hashes with an <tt>:id</tt> value matching an existing associated record
# will update that record. Hashes without an <tt>:id</tt> value will build
# a new record for the association. Hashes with a matching <tt>:id</tt>
# value and a <tt>:_destroy</tt> key set to a truthy value will mark the
# matched record for destruction.
#
# For example:
#
# assign_nested_attributes_for_collection_association(:people, {
# '1' => { :id => '1', :name => 'Peter' },
# '2' => { :name => 'John' },
# '3' => { :id => '2', :_destroy => true }
# })
#
# Will update the name of the Person with ID 1, build a new associated
# person with the name `John', and mark the associatied Person with ID 2
# for destruction.
#
# Also accepts an Array of attribute hashes:
#
# assign_nested_attributes_for_collection_association(:people, [
# { :id => '1', :name => 'Peter' },
# { :name => 'John' },
# { :id => '2', :_destroy => true }
# ])
2 голосов
/ 25 января 2010

В качестве общей практики я бы не предложил использовать обработку исключений в качестве элемента управления для функциональной логики. Поэтому я выступаю за проверку идентификатора -1 и создание человека в этом случае, а не после факта в спасательном блоке.

Если вы ищете причину, 2 я думаю о производительности и ясности.

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

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

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

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