Повторяющиеся записи при использовании update_attributes () и has_many: through - PullRequest
3 голосов
/ 11 ноября 2011

Я не могу понять, почему он генерирует дубликаты recruit_profiles_skills вместо обновления .

class RecruitProfile < ActiveRecord::Base
   has_many :skills, :through => :recruit_profiles_skills
   has_many :recruit_profiles_skills, :dependent => :destroy
   accepts_nested_attributes_for :recruit_profiles_skills, :allow_destroy => true

class Skill < ActiveRecord::Base
    has_many :recruit_profiles, :through => :recruit_profiles_skills
    has_many :recruit_profiles_skills, :dependent => :destroy

Параметры выглядят как

"recruit_profile"=>{
    "recruit_profiles_skills_attributes"=>[{"skill_id"=>"1", "level"=>"15"}]
}

Затем я делаю

def update
    @recruit_profile.update_attributes(params[:recruit_profile])

Но это создает дубликаты записей ассоциации.Почему это не просто обновление !?Я могу предотвратить дубликаты с помощью проверок, но тогда они никогда не обновляются, поскольку они просто хотят создать новую запись, но новая запись недействительна, потому что она не проходит проверку.

1 Ответ

3 голосов
/ 18 ноября 2011

Я решил эту проблему в коде так:

  1. Включите 'id' строки в таблицу ассоциации в каждый атрибут, который уже был создан. Это позволяет обновлению работать должным образом.
  2. Используйте флажок для атрибута skill_id. Таким образом, если флажок не установлен, skill_id не будет отображаться в хэше params. Затем я запускаю этот бит кода

</p>

params[:recruit_profile][:recruit_profiles_skills_attributes].map{ |rps| 
    if rps[:skill_id].nil? then rps[:_destroy] = 1 end 
}

Этот бит кода проверит, установлен ли: skill_id. Если он не установлен, то строку необходимо удалить. Чтобы удалить записи, даже если для параметра: allow_destroy задано значение true, можно добавить значение «: _destroy => 1» key => к хешу. Таким образом, будет присутствовать: id и a: _destroy, поэтому update_attributes удалит его.

Выполнение вышеизложенного позволит создать (:: идентификатор отсутствует, но: skill_id присутствует), обновить (: id присутствует и: skill_id присутствует) и уничтожить (: id присутствует, но: skill_id отсутствует). ИМХО, это не так, как это должно работать, но работа выполняется только с 1 дополнительной строкой кода (разбитой на 3 строки из-за длины).

(ПРИМЕЧАНИЕ: замените skill_id любым другим параметром, также присутствующим в вашей таблице ассоциации. Этот обходной путь необходим, только если вы используете таблицы ассоциации с несколькими атрибутами. В противном случае классический collection_ids = [#, #, #] все еще работает с has_many: через ассоциации.)

...