Rails 4 Обновить вложенные атрибуты
Обновление вложенных атрибутов append вместо обновления внутри имеет много отношений
Я пытаюсь использовать Rails 4 Update_attributes
Class Person <ActiveRecord::Base
has_many :pets
accepts_nested_attributes_for :pets
end
Class Pet < ActiveRecord::Base
belongs_to :person
end
В моем контроллере я возвращаю параметры как
{id: 23, house_no: '22A', pets: [{name: 'jeffy', type: 'dog'}, {name: 'sharky', type: 'fish'}]}
и мой метод обновления
def update
@Person = Person.find(params[:id])
if @Person.update(person_params)
@Person.save
render 'persons/create', status 200
else
render 'persons/create', status 400
end
end
private
def person_params
person_params = params.permit(:house_no)
person_params.merge! ({pets_attributes: params[:pets]}) if params[:pets].present?
person_params
end
Теперь, когда я его обновляю
и если у человека уже есть домашнее животное
затем новые домашние животные добавляются вместо того, чтобы обновляться
например, если лицо с идентификатором 1 имеет 1 домашнее животное с именем "Тигр",
и я обновляю этого человека с двумя домашними животными по имени "Шаша" и "Монти", тогда в записи человека есть 3 домашних животных (Тигр, Шаша и Монти) вместо того, чтобы обновлять его до 2 (Шаша и Монти).
Ответы
Ответ 1
см. руководство:
http://api.rubyonrails.org/v4.0.1/classes/ActiveRecord/NestedAttributes/ClassMethods.html
вам нужно отправить свои атрибуты, например pets_attributes:[{name:'jeffy', type:'dog'}, {name:'sharky', type:'fish'}]
и он должен работать нормально.
Пожалуйста, прочитайте
Теперь вы можете установить или обновить атрибуты на связанных сообщениях через хэш хэша атрибута для члена: включить ключ: posts_attributes с массивом хэшей почтовых атрибутов в качестве значения. Для каждого хеша, у которого нет ключа id a новая запись будет создана, если хеш также не содержит ключ _destroy, который оценивает значение true.
Ответ 2
Обновите модель Person
, как показано ниже:
class Person < ActiveRecord::Base ## NOTE: class (c lowercase) and NOT Class
has_many :pets
accepts_nested_attributes_for :pets, allow_destroy: true ## Added allow_destroy
end
Чтобы уничтожить связанную модель, то есть Pet
через хэш атрибутов, вы должны сначала включить ее, используя параметр :allow_destroy
.
Затем, с вашего вида, вам необходимо передать атрибут _destroy
для домашних животных, которые вы хотите удалить.
Так как вы не использовали общий код вида. Ниже приведен пример того, как это должно быть реализовано в вашем представлении. Измените его в соответствии с вашими требованиями:
<%= form_for @person do |f| %>
<%## .. %>
<%= f.fields_for :pets do |builder| %>
<%## .. %>
<%= builder.check_box :_destroy %>
<%= builder.label :_destroy, "Remove Pet" %>
<% end %>
<% end %>
В приведенном выше коде вам нужно добавить checkbox
и label
для передачи значения _destroy
.
После этого обновите метод person_params
в вашем контроллере, как показано ниже:
def person_params
params.require(:person).permit(:house_no, pets_attributes: [:id, :name, :type, :person_id, :_destroy])
end
ПРИМЕЧАНИЕ.
Вы не должны определять instance variables
с именем с заглавной буквы. Заглавные имена используются для объявления Constants
в Ruby
.
def update
@person = Person.find(params[:id])
if @person.update(person_params)
@person.save
render 'persons/create', status 200
else
render 'persons/create', status 400
end
end
Ответ 3
Можете ли вы попробовать добавить атрибут :id
в :pets_attributes
массив в person_params
?
Вам нужно разрешить атрибут id.
Ответ 4
Вероятно, 1. вы хотите назначить домашних животных отдельно,
@Person.pets = Pets.find(params[:pets])
Или 2. очистите домашних животных до сохранения человека.
@Person.pets.destroy
Ответ 5
Попробуйте изменить person_params
как
def person_params
person_params = params.require(:person).permit(:house_no ,pets_attributes: [:name,:type])
end
И удалите @person.save
из метода обновления. Это вам не нужно. И также используйте !
для update
def update
@Person = Person.find(params[:id])
if @Person.update!(person_params)
render 'persons/create', status 200
else
render 'persons/create', status 400
end
end
Обновление
А также, поскольку я вижу, что в Pet
нет ассоциации belongs_to :person
, добавьте ее в модель
Class Pet < ActiveRecord::Base
belongs_to :person
end
И теперь разрешите атрибут person_id
, добавив его в params
def person_params
person_params = params.require(:person).permit(:house_no,pets_attributes: [:name,:type,:person_id])
end
Ответ 6
Вам нужно изменить параметры с помощью pets_attributes
Также необходимо добавить: id paramter в объекты домашнего животного.