我有三张桌子,如下所示:
广告客户模式:
class Advertiser < ActiveRecord::Base
has_many :advertisers_account_groups
AdvertisersAccountGroup模型
class AdvertisersAccountGroup < ActiveRecord::Base
belongs_to :advertiser
belongs_to :v2_account_account_group, class_name: 'V2Account::AccountGroup', foreign_key: 'account_group_id'
我想知道哪个广告客户属于v2_account_account_groups
并希望获得v2_account_account_groups
。姓名
我尝试了什么;
Advertiser.where(media_type: "line").joins(advertisers_account_groups,v2_account_account_groups)
但它不起作用
答案 0 :(得分:3)
在我看来,您当前的设置使用AdvertisersAccountGroup
作为连接表;因此,我建议使用has_many :through关联。
要做到这一点,您只需要按如下方式切换模型:
class Advertiser < ActiveRecord::Base
has_many :v2_account_account_groups, through: :advertisers_account_groups
has_many :advertisers_account_groups
...
end
class V2Account::AccountGroup < ActiveRecord::Base
has_many :advertisers, through: :advertisers_account_groups
has_many :advertisers_account_groups
...
end
class AdvertisersAccountGroup < ActiveRecord::Base
belongs_to :advertiser
belongs_to :v2_account_account_group, class_name: 'V2Account::AccountGroup', foreign_key: 'account_group_id'
...
end
这样您就可以根据需要查询advertiser
,即advertiser.v2_account_account_groups
。
但是,此关联在广告客户和v2帐户组之间是多对多关系 - 因此,您无法调用advertiser.v2_account_account_groups.name
,因为advertiser.v2_account_account_groups
会返回收藏品而非而不是一个记录。
您可以使用advertiser.v2_account_account_groups.map(&:name)
(以获取所有群组和名称的数组)或advertiser.v2_account_account_groups.first&.name
,但听起来好像您可能需要重新构建数据,如果广告客户应该只有一个v2帐户组。
这是否有意义和听起来像你正在寻找的?如果您有任何疑问,请与我联系。
编辑:
根据您的评论,我认为您应该能够按如下方式构建查询:
Advertiser.includes(advertiser_account_groups: : v2_account_account_group)
.where(advertiser_account_groups: { v2_account_groups: { name: "something" } })
这听起来像你正在寻找的吗?
有几点需要注意:
includes
中的关联时,您希望使用关联名称where
子句时,您需要使用完整的表名,因为它们在数据库中(可通过Model.table_name
搜索)此外,在您的评论中,您引用了添加media_type: "line"
,其中还包括:
Advertiser.includes(advertiser_account_groups: : v2_account_account_group)
.where(media_type: "line", advertiser_account_groups: { v2_account_account_groups: { name: "something" } })
在您的代码中构建此代码的最佳方式可能是广告客户模型中的范围,例如:
scope :by_v2_group_name, -> (name) { includes(advertiser_account_groups: :v2_account_account_group)
.where(media_type: "line", advertiser_account_groups: { v2_account_account_groups: { name: "something" } }) }
或
scope :by_v2_group_name, (lambda do |name|
includes(advertiser_account_groups: :v2_account_account_group)
.where(media_type: "line", advertiser_account_groups: { v2_account_account_groups: { name: "something" } })
end)
然后,您可以保持代码清洁并调用Advertiser.by_v2_group_name("something")
。
让我知道你是如何继续这样做的,我们将根据需要对其进行处理:)
答案 1 :(得分:-1)
只有当您不需要连接表的模型时,此答案才有意义
advertiser_account_gourps 强>
(如果您在该联接表上没有advertiser_id
和account_gourp_id
之外的任何其他属性 - 通常不需要它)
虽然@ SRack的答案是使用has_many :through
关联,但我认为您可以使用简单的多对多关联(has_and_belongs_to_many
),因为在您的图片中我可以看到连接表只有相关表格的ids
(除非您确实需要id
列 - >;在这种情况下,请使用@ SRack的解决方案!)
class Advertiser < ActiveRecord::Base
has_and_belongs_to_many :advertisers_account_groups
class AccountGroup < ActiveRecord::Base
has_and_belongs_to_many :advertisers
然后你可以使用它们来获取它们:
advertiser = Advertiser.first
advertiser.account_groups #to get account groups of that advertiser
反之亦然:
account_group = AccountGroup.first
account_group.advertisers # to get advertisers of that account group
在这种情况下,您需要创建一个迁移来创建连接表:
rails g migration CreateJoinTableAdvertiserAccountGroup advertiser account_group
此表格仅包含相关的advertiser_id
和account_group_id
。
您不需要创建模型并处理该表上的内容,rails将为您填充该表。