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

Вложенный атрибут update_attributes использует вставку, а не обновление

У меня есть пользовательский и вложенный класс профиля следующим образом:

class User < ActiveRecord::Base
  has_one :profile
  attr_accessible :profile_attributes
  accepts_nested_attributes_for :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
  attr_accessible :name
end

user = User.find(1)
user.profile.id  # => 1
user.update_attributes(profile_attributes: {name: 'some name'})
user.profile.id  # => 2

Я не понимаю, почему рельсы выбрасывают старый профиль и создают новый.

Использование

user.profile.update_attributes({name: 'some name'})

просто обновляет текущий профиль, как ожидалось. Но в этом случае я не использую accepts_nested_attributes_for

Кто-нибудь знает, почему обновление происходит таким образом? Я бы предпочел не создавать базу данных строк профиля, не связанных с каким-либо пользователем.

4b9b3361

Ответ 1

Я решил эту проблему, добавив опцию update_only:

accepts_nested_attributes_for :profile, update_only: true

Теперь новый профиль создается только в том случае, если он еще не существует.

Ответ 2

Для всех, у кого такая же проблема в Rails 4: fields_for уже добавляет идентификатор для ваших вложенных форм, но вы должны разрешить параметр id. Мне разрешен только параметр: object_name_id, и поскольку это не вызывает никаких ошибок, мне потребовалось некоторое время, пока я не увидел это в журналах сервера. Надеюсь, это поможет кому-то тратить меньше времени на меня:)

Ответ 3

Если вы проверите свою форму, вам нужно установить атрибут id в хэш-вложенном атрибуте для вашего объекта Profile. Если идентификатор не установлен, ActiveRecord принимает новый объект.

Например, если у вас была форма ERB, создающая набор параметров пользователя с вложенным параметром hash для профиля вложенного профиля внутри пользователя, вы можете включить скрытое значение для идентификатора профиля, например:

<%= hidden_field "user[profile_attributes][id]", @profile.id %>

Ответ 4

Я был поражен этим в другой версии Rails, и я думал, что потеряю рассудок. Добавляя update_only = > true, я решил, что это ошибка в Rails.

Симптомы в моем случае: я бы получил ассоциацию с элементом sort_to deleted и новым вложенным объектом - до тех пор, пока я не обновил страницу. После этого он работал правильно.

В моем случае я добавил метод before_save в свой вложенный класс и распечатал его. Я также распечатал атрибуты перед вызовом update_attributes. Они правильно установили "parent_id" . Я также включил скрытое поле id в форме, без изменений - это было нормально, поскольку оно уже было включено с помощью fields_for...

Сюрприз: я видел один звонок для обновления, генерирующий два вызова сохранения. Первое сохранение имеет идентификатор вложенного объекта, но null для идентификатора belongs_to. - поэтому это приведет к обновлению записи, чтобы установить "parent_id" в значение null. Во втором сохранении будет установлен параметр "parent_id" , но у него будет установлен идентификатор вложенного объекта.

Как я уже сказал, я исправил его, добавив update_only = > true, но я думаю, что это все еще ошибка.

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