Подтвердить что ты не робот

Есть ли метод 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

Мне просто интересно:

  • встроенные решения этой проблемы уже существуют?
  • У моей реализации есть недостатки, которые я не вижу?
4b9b3361

Ответ 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