[Ruby] Rails(ActiveRecord)の多対多関連

今やってる RailsWorkShopの課題では、テーブルが多対多の関連を持っていいます。このへんの知識は無かったので、昨日、じっくりと学習してみました。

課題のテーブル構造 events: 出来事  tags: 出来事に付けるタグ  taggings: 出来事とダグの関連(交差テーブル)

RailsActiveRecordは多対多関連も扱えますが、2つの方法があります。

  • 1. has_and_belongs_to_many (略して habtm)  この方式では交差テーブルの面倒は全てActiveRecordが見てくれます。ただし、交差テーブルには2つのテーブルのid以外のカラムは持てません。単純に多対多を実現した場合はこの方式は便利です。
  • 2. has_many :throw この方式は交差テーブルを介して一対多のテーブルがあるような扱いで、交差テーブルを介しての参照(select, find())は出来ますがActiveRecordはそれ以上の面倒は見てくれません。ただし交差テーブルには任意のカラムが持てます。

今回は、将来タグを付けた事に対しての情報、例えば誰が何時タグ付けしたとかのような情報を扱いたかったので has_many :throw にしました。


上の3つのテーブルに対応するActiveRecord は以下のようになります。

class Event < ActiveRecord::Base
  has_many :taggings
  has_many :tags, :through=>:taggings
end
class Tag < ActiveRecord::Base
  has_many :taggings
  has_many :events, :through=>:taggings
end
class Tagging < ActiveRecord::Base
  belongs_to :event
  belongs_to :tag
end

ここで注意したいのは、has_many に指定する関連名は複数、belongs_to に指定する関連名は単数形とうことです、最初は両方複数形で指定していしてしまい関連しませんでした ^^;

このように関連を持たせると

e = Event.find(1)
puts e.tags

t = Tag.find(3)
puts t.events

のように書く事で関連するレーコードが取得できます。