Создание или обновление ассоциации has_one ActiveRecord - PullRequest
26 голосов
/ 13 января 2012

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

У меня есть два класса:

Property -> has_one :contract  
Contract -> belongs_to :property

В моем классе контракта у меня есть метод create_or_update_from_xml

Сначала я проверяю, существует ли указанное свойство.

property_unique_id = xml_node.css('property_id').text
      property = Property.find_by_unique_id(property_unique_id)
      next unless property

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

if property.contract.nil?
  # create a new one and populate it with attributes
else
  # use the existing one and update it with attributes

Я знаю, как бы я поступил, если бы это был неформатированный SQL, но я не могу разобраться с подходом ActiveRecord.

Любые намеки за этот блокпост были бы очень благодарны.

Заранее спасибо.

Ответы [ 3 ]

35 голосов
/ 14 января 2012
if property.contract.nil?
  property.create_contract(some_attributes)
else
  property.contract.update_attributes(some_attributes)
end

Должен сделать свое дело.Когда у вас есть ассоциация has_one или belongs_to, вы получаете методы build_foo и create_foo (которые похожи на Foo.new и Foo.create).Если связь уже существует, то property.contract - это просто обычный объект активной записи.

19 голосов
/ 02 мая 2016

Просто еще один способ сделать это, используя ruby ​​OR-Equal trick

property.contract ||= property.build_contract
property.contract.update_attributes(some_attributes)

Обновление:

@ KayWu прав, приведенный выше трюк || = создаст объект контракта вПервая линия, а не просто его строительство.Альтернативой будет

property.build_contract unless property.contract
property.contract.update_attributes(some_attributes)
9 голосов
/ 31 июля 2013
Property.all.each do |f|
  c = Contract.find_or_initialize_by(property_id: f.id)
  c.update(some_attributes)
end

Я не знаю, является ли это лучшим решением, но для меня это более кратко

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