у меня есть Person
модели и Business
модели оба из которых have_many contacts, as:contactable
Rails вложенной модель форма ошибки обновляемых дети
Я не уверен, как правильно обновить вложенную модель, но то, что я сделал это следующим образом :
мой PARAMS хэш следующим образом:
{"person"=>
{"name"=>"updated name",
.......
"contacts_attributes"=>
{"0"=>{"contact_type"=>"web", "contact_sub_type"=>"main", "address"=>"http:www.example.com/changed", "id"=>"2"},
"1"=>{"contact_type"=>"twitter", "contact_sub_type"=>"main", "address"=>"changedtwerson", "id"=>"4"},
"2"=> {contact_type: "facebook", contact_sub_type: "main" , id: "3" },
"3"=> {contact_type: "email", contact_sub_type: "main",id: "1" }
}},
"submit"=>"save",
"id"=>"1",
"controller"=>"persons",
"action"=>"update"}
в рамках модели у меня уже есть 3 person.contacts
для Contact.contact_type
"Сети", "Facebook" и "Twitter" с contact_sub_type
, соответствующий введенным выше входам.
В Контактной модели у меня есть validates_uniqueness_of :contact_type, scope: [:contact_sub_type, :contactable_id ]
Потому что, если адрес является пустым, я не хочу, чтобы загрузить контакт с человеком/объектом бизнеса я включил в методе, чтобы установить сильный код Params в destroy_all записи, которые не имеют адрес:
def person_params
contact_list = params[:person][:contacts_attributes].delete_if { |key, value| value[:address].blank? } if params[:person].present? && params[:person][:contacts_attributes].present?
cl_ary = []
contact_list.values.each { |v| cl_ary << v[:id] }
@person.contacts.where.not(id: cl_ary).destroy_all if @person && @person.contacts
params.require(:person).permit(:name, ......
contacts_attributes: [:id, :address, :contact_type, :contact_sub_type]) unless params[:person].nil?
end
Когда я называю @person = Person.find (ID: Params [: ID]) @ person.update person_params
я получаю значение ложь возвращается и @person недействительна как :contact_type=>["has already been taken"]
после обновления @person.contacts
дает мне следующее (что мне следует пройти уникальную проверку)
[#<Contact id: 4, contact_type: "twitter", contact_sub_type: "main", address: "changedtwerson", contactable_id: 1, contactable_type: "Person", created_at: "2014-12-12 10:09:15", updated_at: "2014-12-12 10:09:24">, #<Contact id: 2, contact_type: "web", contact_sub_type: "main", address: "http:www.example.com/changed", contactable_id: 1, contactable_type: "Person", created_at: "2014-12-12 10:09:15", updated_at: "2014-12-12 10:09:24">]
поэтому у меня есть 2 вопроса:
- У меня есть действительный подход здесь, я пропустил что-нибудь и есть лучший способ?
- Как я могу взглянуть дальше на проверку и выяснить, почему проверка не выполняется, когда она выглядит ОК визуально?
Спасибо, вы просто бить меня к этому изменению. Однако он позволяет только удалять контакты из хэша params, которые имеют пустой адрес. Person_params возвращает хэш только с контактами с адресом.Однако, если существующий человек имеет 4 контакта и 1 указан в хеше (после отклонения), 3 следует удалить из db, и это то, что пытается выполнить вторая часть (destroy_all). Путем простого отклонения адресов пробелов 1 обновляется, а остальные 3 остаются неизмененными, а не удаляются. – Richbits
В моем документе неверные данные не должны быть сохранены в БД. Проверка модели должна предотвращать такой сценарий. Если у вас уже есть поврежденные данные, чем удалить их вручную. – olhor
Абсолютно согласен. Все контакты в базе данных имеют адрес, но когда это отображается в форме, пользователь может удалить адрес, а затем он будет отправлен как недопустимая запись (это потому, что у меня есть скрытые поля в форме, классифицирующей поле (id/contact_type/sub_type) ... Я обновлю этот вопрос, чтобы отразить это. Это пустые записи, которые reject_if удалит, но если они сохранены в обновлении базы данных, они автоматически не удалят их, поэтому действие destroy_all. – Richbits