QA@IT

railsのmodelの関連付けについて

4243 PV

hogeは複数のfooとbarを持ち、fooは複数のbarを持つといったときに

class hoge < ActiveRecord::Base
  has_many :foos
  has_many :bars
end
class foo < ActiveRecord::Base
  belongs_to :hoge
  has_many :bars
end
class bar < ActiveRecord::Base
  belongs_to :hoge
  belongs_to :foo
end

fooはhogeの関連先のID hoge_idをもち、barは関連先のID hoge_idとfoo_idをもっています

以上のようにしたのですが

hoge.foos.find(foo_id).bars.new(params)

としたときにnewされたbarはfoo_idを持っているのですがhoge_idを持っていない状態となってしまいます
barがhoge_idとfoo_idを持った状態にするにはどうしたら良いでしょうか

  • ちょっとモデル間の関係がよくわかりません。具体的な例にしていただいたほうが回答しやすいと思います。一番気になるのは「Bar は、依存する Foo が依存している以外の Hoge に依存することができるか」なのですが、この一文だけ見ても抽象的でわかりづらいですよね。 -
  • 実用としてではなく自動的にすべての親IDをもたせることは可能であるのか知りたかっただけなのです。。
    >「Bar は、依存する Foo が依存している以外の Hoge に依存することができるか」
    については依存することは出来ないということで質問をさせてもらいました。
    具体例もあげることができないのに質問してしまい申し訳ないです
    -

回答

結論からいうと Foo#bars.build で作成した Bar に自動的に hoge_id をセットする方法は用意されていないと思います。foo.bars.new(params.merge(hoge: foo.hoge)) のように明示するのが素直な方法でしょうか。

あるいは Foo に適当なメソッドを定義して、あらかじめ hoge_id をセットしても良いかも知れません。

class Foo < ActiveRecord::Base
  # Example: Foo.find(1).build_bar_with_hoge
  def build_bar_with_hoge
    bars.build(hoge: hoge)
  end
end

RDBMS 的には、

  • foos テーブルの主キーは hoge_id と id
  • bars テーブルの外部キーは hoge_id と foo_id

というのが綺麗なかたちかと思いますが、Rails は基本的に、複合キー / 複合外部キーを考慮していないために、やや扱いが面倒になります。

bars テーブルに hoge_id を持たせず、下記のようなメソッドを定義して、間接的に依存する Hoge を参照すると Rails 的には素直に書けますが、パフォーマンスは落ちるので悩ましいところですね。

class Bar < ActiveRecord::Base
  belongs_to :foo
  # Example: Bar.find(1).hoge
  def hoge
    foo.hoge if foo
  end
end
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。