ActiveRecordのhas_many :throughでn:nをやる時にハマっている件
Rails(2.3.5)でハマっている。
hoge,fugaの2テーブルを中間テーブルhoge_fugaを使い、
ActiveRecordのhas_many :throughでn:nにしたい。
class Hoge < ActiveRecord::Base set_primary_key 'hoge_id' has_many :hoge_fugas, :foreign_key => 'hoge_id', :dependent => :destroy has_many :fugas, :through => :hoge_fugas accepts_nested_attributes_for :fugas end class Fuga < ActiveRecord::Base set_primary_key 'fuga_id' has_many :hoge_fugas, :foreign_key => 'fuga_id', :dependent => :destroy has_many :hoges, :through => :hoge_fugas end class HogeFuga < ActiveRecord::Base set_primary_key 'hoge_fuga_id' belongs_to :hoge, :foreign_key => 'hoge_id' belongs_to :fuga, :foreign_key => 'fuga_id' end
こういうふうにmodelを作った後、
hoge=Hoge.new hoge.fugas<<Fuga.new hoge.fugas<<Fuga.new hoge.save
とやったら、中間テーブルのhoge_fugaに4レコード出来てしまった。
暫定的に以下のように回避してるけど気持ち悪い。
.save(false)してるのは、実際にはfugasが1件以上という条件で
Hogeのvalidationを定義しているため。
hoge=Hoge.new hoge.fugas<<Fuga.new hoge.fugas<<Fuga.new fugas = hoge.fugas.dup hoge.save(false) hoge.fugas = fugas
追記
Hoge classに↓を付けてるのを忘れてた。
accepts_nested_attributes_for :fugas
hoge=Hoge.new({"fugas_attributes"=>{"0"=>{}, "1"=>{}}}) hoge.save
でも、中間テーブルのhoge_fugaに4レコード出来てしまう。
原因はまさしくaccepts_nested_attributes_forだったそうで、
#3659 accepts_nested_attributes_for causes duplicate entries in join model table - Ruby on Rails - rails
Rails2.3.6以降(2.3.6,2.3.7はバギーとのことなので今だと2.3.8)に
するのが根本的な解決法のようです。
とりあえず上のやり方で対処しておいて、コメントに
「Rails2.3.8以降に更新したらhoge.saveで可」
のように書いておくとする。