自参考轨道具有三元关系

时间:2015-07-07 03:37:03

标签: ruby-on-rails database

我正在建立一个社交网站,其中会员可以邀请其他会员参加活动,这是ERD的样子图片

https://41.media.tumblr.com/14f889d005b1df1c123500a0de133cb6/tumblr_nr3m0dUgIL1r3syg3o1_400.png

如何在迁移和模型中设置关系? rails文档处理二元关系。

2 个答案:

答案 0 :(得分:0)

成员/邀请/事件关系通常可以如下所示:

<强>模型

class Member < ActiveRecord::Base
 has_many :invites
end

class Event < ActiveRecord::Base
 has_many :members, :through :invites
end

class Invite < ActiveRecord::Base
 belongs_to :member
end

此建模向我们展示了一个成员有很多邀请,其中每个邀请都属于特定事件。现在,您希望能够访问特定事件的所有成员(收到邀请的成员);这是通过使用has_many :through关联来完成的。

希望这有帮助

答案 1 :(得分:0)

通过将class_names和foreign_keys提供给has_many关系,您可以根据需要为关联命名。 Invitation模型将作为联接,将您的活动链接到互相邀请的会员。

class Member < ActiveRecord::Base
   has_many :invites, class_name: "Invitation", foreign_key: "invited_member_id"
   has_many :invitees, class_name: "Invitation", foreign_key: "inviting_member_id"
end

class Invitation < ActiveRecord::Base
   belongs_to :event
   belongs_to :inviting_member, class_name: "Member"
   belongs_to :invited_member, class_name: "Member" 
end

class Event < ActiveRecord::Base
    has_many :invitations
    has_many :invited_members, through: :invitations
    has_many :inviting_members, through: :invitations
end

可以这样使用..

?> m1 = Member.find 1
=> #<Member id: 1, username: "user1", created_at: "2015-07-07 04:01:41", updated_at: "2015-07-07 04:01:41">
>> m2 = Member.find 2
=> #<Member id: 2, username: "user2", created_at: "2015-07-07 04:01:43", updated_at: "2015-07-07 04:01:43">
>> e = Event.create name: "my cool event"
=> #<Event id: 2, name: "my cool event", created_at: "2015-07-07 04:11:49", updated_at: "2015-07-07 04:11:49">
>> Invitation.create event: e, inviting_member: m, invited_member: m2
=> #<Invitation id: 2, event_id: 2, inviting_member_id: 1, invited_member_id: 2, created_at: "2015-07-07 04:12:01", updated_at: "2015-07-07 04:12:01">
>> m1.reload
=> #<Member id: 1, username: "user1", created_at: "2015-07-07 04:01:41", updated_at: "2015-07-07 04:01:41">
>> m1.invites
=> #<ActiveRecord::Associations::CollectionProxy []>
>> m1.invitees
=> #<ActiveRecord::Associations::CollectionProxy [#<Invitation id: 1, event_id: 1, inviting_member_id: 1, invited_member_id: 2, created_at: "2015-07-07 04:03:58", updated_at: "2015-07-07 04:03:58">, #<Invitation id: 2, event_id: 2, inviting_member_id: 1, invited_member_id: 2, created_at: "2015-07-07 04:12:01", updated_at: "2015-07-07 04:12:01">]>

>> e = Event.first
=> #<Event id: 1, name: "Cool", created_at: "2015-07-07 04:01:54", updated_at: "2015-07-07 04:01:54">

>> e.inviting_members
 => #<ActiveRecord::Associations::CollectionProxy [#<Member id: 1, username: "user1", created_at: "2015-07-07 04:01:41", updated_at: "2015-07-07 04:01:41">]>
>> e.invited_members
=> #<ActiveRecord::Associations::CollectionProxy [#<Member id: 2, username: "user2", created_at: "2015-07-07 04:01:43", updated_at: "2015-07-07 04:01:43">]>

邀请迁移:

class CreateInvitations < ActiveRecord::Migration
  def change
    create_table :invitations do |t|
      t.references :event, index: true, foreign_key: true
      t.integer :inviting_member_id
      t.integer :invited_member_id

      t.timestamps null: false
    end
  end
end