2016-04-27 4 views
2

Дарите две модели, с has_one ассоциации:has_one отношение автоматически устанавливается ноль, если более чем один

class ShopInfo 
    belongs_to :shop 
end 

class Shop 
    has_one :shop_info 
end 


s = Shop.create 
ss1 = s.create_shop_info 

В каком-то другом месте моего кода я

ss2 = s.create_shop_info 

После этого SS1. shop_id установлен на nil, поэтому ss1 теперь является сиротой.

Есть ли способ удалить предыдущие записи вместо того, чтобы установить их в нуль?

+0

Почему не обновлять предыдущую shop_info запись, а не создать новую? – Joeyjoejoe

+0

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

ответ

3

По умолчанию has_one объединение выполняет оператор nullify. Добавление dependent: :destroy решило проблему.

class Shop 
    has_one :shop_info, dependent: :destroy 
end 

Просто если кто-то хочет больше информации, код ActiveRecord для замены has_one записи заключается в следующем:

https://github.com/rails/rails/blob/v4.2.6/activerecord/lib/active_record/associations/has_one_association.rb#L24-L51

НО если добавить dependent опцию в ассоциации, выполняет метод delete, а также :

https://github.com/rails/rails/blob/v4.2.6/activerecord/lib/active_record/associations/has_one_association.rb#L7-L22

+0

Это должно быть принято как ответ! Не знал, что зависимая опция работает именно так. –

+0

, потому что это мой собственный ответ, я должен подождать два дня, чтобы принять его :( –

1

Фрэно, если вы посмотрите на the has_one documentation, я думаю, что вы хотите использовать association= метод:

ассоциации = (адъюнкт)

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

Что означает, что ваш код может выглядеть ...

ss2.shop_info = ShopInfo.new(...) 
+0

Спасибо за ваше предложение. Я нашел решение, снова прочитав документацию. К сожалению, ваше решение не мешает другим разработчикам иметь ту же проблему, что и попытка вызова create_shop_info. –

Смежные вопросы