n:n リレーションシップ

中間テーブルも弄りたい, とか思い始めたよ. habtm(has_and_belongs_to_many) でも行けるのかもしれないけど, has_many() + has_many(:through => ) で.

例として

  • Paper には複数の Authors がいる(場合もある)
    • Authors には順番が存在している
  • Author は複数の Papers を持っている(…場合もある)

こんな時. 中間テーブルとして Priorities(名前が変だが) を作成してみる.
Priorities は

def self.up
  create_table(:priorities) do |t|
    t.column(:author_id, :integer)
    t.column(:paper_id, :integer)
    t.column(:priority, :integer)
  end
end

def self.down
  drop_table(:priorities)
end

みたいに作ってやる(migrate).

でもって model で

# app/models/paper.rb
class Paper < ActiveRecord::Base
  has_many(:priorities, :order => :priority)
  has_many(:authors, :through => :priorities, :order => :priority)
end

# app/models/author.rb
class Author < ActiveRecord::Base
  has_many(:priorities, :order => :priority)
  has_many(:papers, :through => :priorities, :order => :priority)
end

# app/models/priority.rb
class Priority < ActiveRecord::Base
  belongs_to(:author)
  belongs_to(:paper)
  act_as_list(:scope => :paper_id)
end

みたいな. これで複数の author に順番が作成された訳ですが.
正しく動くけど, もっと良い方法がありそうな気がする(実は中間テーブル不要, とか).

あとは登録の所でちょっとゴニョゴニョと. ToDo は dependent です.