我有三个表,如下所示:

mysql - Rails Active Record:如何联接三个表?-LMLPHP

广告商型号:

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 .name

所需输出:
mysql - Rails Active Record:如何联接三个表?-LMLPHP

我尝试过的

Advertiser.where(media_type: "line").joins(advertisers_account_groups,v2_account_account_groups)


但这不起作用

最佳答案

在我看来,您当前的设置使用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")

让我知道您的情况,我们将根据需要进行工作:)

10-06 06:14