Rails 4.0 で多対多関連
この記事内では、"timeline"モデルと,"user"モデルをどのようにして接続する事が出来るかを見ていきます。
timeline.user user.timeline
等でアクセス出来るように作っています(つもりです)。
Rubyや、Railsの経験が浅いため、もっと良い方法を知っている方、間違えを見つけた方はコメントを頂けるととてもうれしいです。
またポリモーフィズムを使用した関連付けに関しては触れていません。
あくまで導入部分だと思って参照して頂ければとおもいます。
HABTM
has_and_belongs_to_many を使った例。
モデルをいくつかの種類に分けて参照させたいときなどに便利です。
#/app/models/user.rb class User < ActiveRecord::Base has_and_belongs_to_many :timelines_member, :class_name => 'Timeline', :foreign_key => :member_timeline_id, :association_foreign_key => :member_id, :join_table => :timelines_members has_and_belongs_to_many :timelines_observer, :class_name => 'Timeline', :foreign_key => :observer_timeine_id, :association_foreign_key => :observer_id, :join_table => :timelines_observers end
#/app/models/timeline.rb class Timeline < ActiveRecord::Base has_and_belongs_to_many :members, :class_name => 'User', :foreign_key => :member_id, :association_foreign_key => :member_timeline_id, :join_table => :timelines_members has_and_belongs_to_many :observers, :class_name => 'User', :foreign_key => :observer_id, :association_foreign_key => :observer_timeine_id, :join_table => :timelines_observers end
#/db/migrate/[TIMESTAMP]_timelines_members.rb class TimelinesMembers < ActiveRecord::Migration def change create_table :timelines_members, id: false do |t| t.integer :member_id, null: false t.integer :member_timeline_id, null: false end add_index(:timelines_members, [:member_id, :member_timeline_id], :unique => true) end end
#/db/migrate/[TIMESTAMP]_timelines_obserbers.rb class TimelinesObservers < ActiveRecord::Migration def change create_table :timelines_observers, id: false do |t| t.integer :observer_id, null: false t.integer :observer_timeline_id, null: false end add_index(:timelines_observers, [:observer_id, :observer_timeline_id], :unique => true) end end
HM with relationship table
has_manyとbelongs_toで関連を作るのですが、2つのモデルの間にrelationshipテーブルを挟む方法です。
2つのモデルの間に”状態”等のステータスを持たせたい場合に有効です。
#/app/models/user.rb has_many :timeline_user_relationships has_many :timelines, :through => :timeline_user_relationships end
#/app/models/timeline.rb class Timeline < ActiveRecord::Base has_many :timeline_user_relationships has_many :users, :through => :timeline_user_relationships end
#/app/models/timeline_user_relationship.rb class TimelineUserRelationship < ActiveRecord::Base belongs_to :user belongs_to :timeline end
#/db/migrate/[TIMESTAMP]_create_timeline_user_relationships.rb class CreateTimelineUserRelationships < ActiveRecord::Migration def change create_table :timeline_user_relationships do |t| t.references :user, index: true t.references :timeline, index: true t.integer :role t.timestamps end add_index(:timeline_user_relationships, [:user_id, :timeline_id], :unique => true) end end
create_join_table
Rails 4.0から追加されたものです。
Railsドキュメントにも記載されています。
http://railsdoc.com/migration#テーブルを結合して作成(create_join_table)
手軽に作成出来るので、とりあえず関連をつけたいという時に使うと良いかと思います。
#/app/models/user.rb class User < ActiveRecord::Base has_and_belongs_to_many :timelines end
#/app/models/timeline.rb class Timeline < ActiveRecord::Base has_and_belongs_to_many :users end
#/db/migrate/[TIMESTAMP]_create_timelines_users.rb class CreateUsersGroups < ActiveRecord::Migration def change create_join_table :timelines, :users add_index(:groups_users, [:group_id, :user_id], :unique => true) end end
ざっと3種類紹介しましたが、option等は必要になった際に使ってみて追加していこうと思います。