Есть ли метод first_or_build в has_many ассоциациях?
В рельсах 3.2+ вы можете сделать это:
SomeModel.some_scope.first_or_initialize
Что вы также можете сделать:
OtherModel.some_models.first_or_initialize
Я нахожу это довольно полезным, но мне бы хотелось иметь метод first_or_build
в моих ассоциациях has_many
, который будет действовать как first_or_initialize
, но также добавит новую запись в ассоциацию как build
, когда необходимо.
обновление для уточнения: да, я знаю о first_or_initialize
и first_or_create
. Thing is, first_or_initialize
не добавляет инициализированную запись в цель ассоциации как build
, а first_or_create
... ну... создает запись, которая не является целью.
У меня есть решение, которое работает, используя расширения расширений:
class OtherModel < ActiveRecord::Base
has_many :some_models do
def first_or_build( attributes = {}, options = {}, &block )
object = first_or_initialize( attributes, options, &block )
proxy_association.add_to_target( object ) if object.new_record?
object
end
end
end
Мне просто интересно:
- встроенные решения этой проблемы уже существуют?
- У моей реализации есть недостатки, которые я не вижу?
Ответы
Ответ 1
Я не уверен, что в рельсы есть что-то, что будет делать именно то, что вы хотите, но вы могли бы имитировать код first_or_initialize с более кратким расширением, чем вы сейчас используете, что, я считаю, делает то, что вы хотите, и заверните его в расширение многократного использования, например следующее. Это написано с расширением Rails 3.2.
module FirstOrBuild
def first_or_build(attributes = nil, options = {}, &block)
first || build(attributes, options, &block)
end
end
class OtherModel < ActiveRecord::Base
has_many :some_models, :extend => FirstOrBuild
end