rails 中两个表之间的两个或多个多对多关系
Two or more Many to Many relationships between two tables in rails
我有两个表:
Users
和 Groups
一个用户has_many组和一个组,has_many一个用户:
u = User.last
u.groups
g = Group.last
g.users
假设我出于某种奇怪的原因想要第二个不同组的列表。再次,一个用户有多个组(在本例中称为 other_group),一个组有很多用户。
u = User.last
u.other_groups
g = Group.last
g.other_users
如何使用 Active Record 两次关联此关系中的两个模型?我需要多个 has 和 belongs to many tables 吗?也许 a 拥有并属于许多 "through"。这看起来像什么?
答案:
class Matter < ActiveRecord::Base
has_many :matters_lawfirms
has_many :matters_other_lawfirms
has_many :lawfirms, class_name: 'Lawfirm', through: :matters_lawfirms, :source => :lawfirm
has_many :other_lawfirms, class_name: 'Lawfirm', through: :matters_other_lawfirms, :source => :lawfirm
end
class Lawfirm < ActiveRecord::Base
has_many :matters_lawfirms
has_many :matters_other_lawfirms
has_many :matters, class_name: 'Matter', through: :matters_lawfirms, :source => :matter
has_many :other_matters, class_name: 'Matter', through: :matters_other_lawfirms, :source => :matter
end
class MattersLawfirm < ActiveRecord::Base
belongs_to :matter
belongs_to :lawfirm
end
class MattersOtherLawfirm < ActiveRecord::Base
belongs_to :matter
belongs_to :lawfirm
end
迁移:
class AddMatterOtherLawfirms < ActiveRecord::Migration
def change
create_table :matters_other_lawfirms, :id => false do |t|
t.references :matter, :lawfirm
end
add_index :matters_other_lawfirms, [:matter_id, :lawfirm_id],
name: "matters_other_lawfirms_index",
unique: true
end
end
class AddMatterLawfirmsHabtmt < ActiveRecord::Migration
def change
create_table :matters_lawfirms, :id => false do |t|
t.references :matter, :lawfirm
end
add_index :matters_lawfirms, [:matter_id, :lawfirm_id],
name: "matters_lawfirms_index",
unique: true
end
end
您根本无法使用 belong_to
定义多对多关系
您应该实施 has_and_belongs_to_many
或 has_many :through
关系,而不是 has_many
- belongs_to
关系。
编辑
好的,我想我现在明白了,
您无法使用单个 has_and_belongs_to_many table 实现此目的,我会选择 has_many :through 关系。如果您只有两个组类别,请在您的加入中为该类别设置一个标志 table。
尚未测试,但类似的东西应该可以工作
class GroupMembership #.. with category field or something
belongs_to :group
belongs_to :user
class User
has_many :group_memberships
has_many :local_groups, -> { where group_memberships: { category: 'local' } }, :through => :group_memberships, :source => :group
has_many :outside_groups, -> { where group_memberships: { category: 'outside' } }, :through => :group_memberships, :source => :group
class Group
has_many :group_memberships
has_many :local_users, -> { where group_memberships: { category: 'local' } }, :through => :group_memberships, :source => :user
has_many :outside_users, -> { where group_memberships: { category: 'outside' } }, :through => :group_memberships, :source => :user
对于 HABTM 关系,您需要定义多个连接 table。
假设您已经知道如何处理数据模型中的 has_many 关系(Alper 似乎要写到这一点),在两个表之间容纳多个关系非常容易(我现在正在做一些事情这涉及将用户明确地链接到他们正在从事的项目以及他们拥有的项目。我相信这与您要实现的目标非常相似)。代码看起来像这样:
用户模型
has_many :regular_groups, class_name: 'Group', through: :user_regular_groups
has_many :other_groups, class_name: 'Group', through: :user_other_groups
群模型
has_many :regular_users, class_name: 'User', through: :user_regular_groups
has_many :other_users, class_name: 'User', through: :user_other_groups
显然,在这种情况下,我们使用了两个不同的关联表(user_regular_groups 和 user_other_groups),但是您可以使用一个范围来完成类似的事情(沿着 Alper 的思路)推荐)。
希望对您有所帮助!
我有两个表:
Users
和 Groups
一个用户has_many组和一个组,has_many一个用户:
u = User.last
u.groups
g = Group.last
g.users
假设我出于某种奇怪的原因想要第二个不同组的列表。再次,一个用户有多个组(在本例中称为 other_group),一个组有很多用户。
u = User.last
u.other_groups
g = Group.last
g.other_users
如何使用 Active Record 两次关联此关系中的两个模型?我需要多个 has 和 belongs to many tables 吗?也许 a 拥有并属于许多 "through"。这看起来像什么?
答案:
class Matter < ActiveRecord::Base
has_many :matters_lawfirms
has_many :matters_other_lawfirms
has_many :lawfirms, class_name: 'Lawfirm', through: :matters_lawfirms, :source => :lawfirm
has_many :other_lawfirms, class_name: 'Lawfirm', through: :matters_other_lawfirms, :source => :lawfirm
end
class Lawfirm < ActiveRecord::Base
has_many :matters_lawfirms
has_many :matters_other_lawfirms
has_many :matters, class_name: 'Matter', through: :matters_lawfirms, :source => :matter
has_many :other_matters, class_name: 'Matter', through: :matters_other_lawfirms, :source => :matter
end
class MattersLawfirm < ActiveRecord::Base
belongs_to :matter
belongs_to :lawfirm
end
class MattersOtherLawfirm < ActiveRecord::Base
belongs_to :matter
belongs_to :lawfirm
end
迁移:
class AddMatterOtherLawfirms < ActiveRecord::Migration
def change
create_table :matters_other_lawfirms, :id => false do |t|
t.references :matter, :lawfirm
end
add_index :matters_other_lawfirms, [:matter_id, :lawfirm_id],
name: "matters_other_lawfirms_index",
unique: true
end
end
class AddMatterLawfirmsHabtmt < ActiveRecord::Migration
def change
create_table :matters_lawfirms, :id => false do |t|
t.references :matter, :lawfirm
end
add_index :matters_lawfirms, [:matter_id, :lawfirm_id],
name: "matters_lawfirms_index",
unique: true
end
end
您根本无法使用 belong_to
定义多对多关系您应该实施 has_and_belongs_to_many
或 has_many :through
关系,而不是 has_many
- belongs_to
关系。
编辑
好的,我想我现在明白了,
您无法使用单个 has_and_belongs_to_many table 实现此目的,我会选择 has_many :through 关系。如果您只有两个组类别,请在您的加入中为该类别设置一个标志 table。
尚未测试,但类似的东西应该可以工作
class GroupMembership #.. with category field or something
belongs_to :group
belongs_to :user
class User
has_many :group_memberships
has_many :local_groups, -> { where group_memberships: { category: 'local' } }, :through => :group_memberships, :source => :group
has_many :outside_groups, -> { where group_memberships: { category: 'outside' } }, :through => :group_memberships, :source => :group
class Group
has_many :group_memberships
has_many :local_users, -> { where group_memberships: { category: 'local' } }, :through => :group_memberships, :source => :user
has_many :outside_users, -> { where group_memberships: { category: 'outside' } }, :through => :group_memberships, :source => :user
对于 HABTM 关系,您需要定义多个连接 table。
假设您已经知道如何处理数据模型中的 has_many 关系(Alper 似乎要写到这一点),在两个表之间容纳多个关系非常容易(我现在正在做一些事情这涉及将用户明确地链接到他们正在从事的项目以及他们拥有的项目。我相信这与您要实现的目标非常相似)。代码看起来像这样:
用户模型
has_many :regular_groups, class_name: 'Group', through: :user_regular_groups
has_many :other_groups, class_name: 'Group', through: :user_other_groups
群模型
has_many :regular_users, class_name: 'User', through: :user_regular_groups
has_many :other_users, class_name: 'User', through: :user_other_groups
显然,在这种情况下,我们使用了两个不同的关联表(user_regular_groups 和 user_other_groups),但是您可以使用一个范围来完成类似的事情(沿着 Alper 的思路)推荐)。
希望对您有所帮助!