Как обновить существующий вложенный атрибут без FK

Предполагая, что у пользователя есть_один :подписка, подписка принадлежит_к:пользователь, и я использую accepts_nested_attributes_for для вложения атрибутов подписки в форму создания пользователя, как лучше всего найти и обновить существующую подписку (если она существует) на основе User.email == Подписка.email?

Обратите внимание, что существующие подписки могут иметь user_id = nil.


person Eric M.    schedule 02.12.2010    source источник


Ответы (2)


Вероятно, вы хотите использовать электронную почту в качестве внешнего ключа:

class User < ActiveRecord::Base
  has_one :subscription, :foreign_key => "email", :primary_key => "email"
end
person Keith Gaddis    schedule 02.12.2010
comment
Хм, да... Я думал об этом. Позвольте мне поиграть с этой идеей. Спасибо. - person Eric M.; 02.12.2010
comment
Я делал это время от времени. Работает очень хорошо, кроме того, что это естественный ключ, а это означает, что вы столкнетесь с проблемами, когда пользователи захотят изменить свои адреса электронной почты. просто убедитесь, что у вас есть индекс электронной почты для обеих таблиц. - person Keith Gaddis; 02.12.2010
comment
Хорошо, я настроил ассоциации, но все еще получаю повторяющиеся записи. У меня есть update_only =› true для accepts_nested_attributes_for. Любые идеи? - person Eric M.; 02.12.2010
comment
Проблема может заключаться в том, что электронное письмо о подписке не доставляется через форму, а устанавливается как... before_save { self.email = user.email if user }. Точно сказать не могу... - person Eric M.; 02.12.2010
comment
в этом случае вам, вероятно, понадобится некоторая пользовательская логика в вашем контроллере для ее обработки. вложенные атрибуты могут быть не тем решением, которое вы ищете. - person Keith Gaddis; 02.12.2010

Я полагаю, что это нужно будет разделить на двухэтапный процесс:

  1. Найдите пользователя, которого хотите обновить.
  2. Найдите подписку (если есть) с адресом электронной почты пользователя. Установите для пользователя подписку на эту запись.
  3. Обновите пользователя как обычно. Поскольку ассоциация теперь присутствует (т. е. user.subscription не будет равна нулю), записи подписки будут обновляться правильно.
person Ryan Brunner    schedule 02.12.2010