我有两个表,users
和groups
。一个用户拥有一个组,并且可以是多个组的一部分。一个组属于一个用户,并且可以有多个用户。
因此,对于我的user
模型,我有
has_and_belongs_to_many :groups
has_many :groups
而对于我的group
型号,我有
has_and_belongs_to_many :users
belongs_to :user
我的迁移中还有一个联接表。。
def change
create_table :groups_users, :id => false do |t|
t.integer :group_id
t.integer :user_id
end
end
我的问题是,这有道理吗?把has_many
和belongs_to
放在has_and_belongs_to_many
上面,我觉得我做错了什么。
我处理这个问题的方式,这是我自己的方法,是使用3个表/模型,如下所示:
group_user.rb
class GroupUser < ActiveRecord::Base
attr_accessible :user_id, :group_id
belongs_to :group
belongs_to :user
end
组.rb
class Group < ActiveRecord::Base
attr_accessible :owner_id
validates_presence_of :owner_id
has_many :group_users
has_many :users, through: :group_users
end
user.rb
class User < ActiveRecord::Base
attr_accessible :some_attributes
has_many :group_users
has_many :groups, through: :group_users
end
然后,无论何时创建Group
对象,创建该对象的User
都会将其id
放置在Group
的owner_id
属性中,并将其自身放入GroupUser
表中。
为了避免多个外键指向同一关系,另一种选择是使用联接模型,然后在联接模型上添加一个标志来表示用户是否是所有者。
例如:
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, through: :memberships
has_many :owned_groups, through: memberships, conditions: ["memberships.owner = ?", true], class_name: "Group"
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
#This model contains a boolean field called owner
#You would create a unique constraint on owner, group and user
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
has_one :owner, through: :memberships, conditions: ["memberships.owner = ?", true], class_name: "User"
end