ActiveRecord联接在where子句中添加位置

时间:2019-07-18 22:06:38

标签: sql postgresql activerecord

我有以下很好的查询。但是,我想在穿透表上指定replier_fb_groupremoved_on为空的条件

groups = FbGroup.joins(:replier_accounts).where(
  id: group_ids,
  :replier_accounts => { active: true }
 ).group('fb_groups.id'
 ).having('count(replier_accounts) > 0')

我尝试过的

FbGroup.joins(:replier_fb_groups, :replier_accounts).where(
  id: group_ids,
  :replier_fb_groups => { removed_on: nil},
  :replier_accounts => { active: true }
).group('fb_groups.id'
).having('count(replier_accounts) > 0')

我如何才能在hading子句中做到这一点,您只计算满足其replier_accounts的条件而replier_fb_group为零的removed_on

1 个答案:

答案 0 :(得分:0)

您正在寻找的是通过FbGroup通过ReplierAccountsReplierFbGroups连接的一种方法。在这里,我假设ReplierFbGroups是一个包含idsFbGroup两者中的ReplierAccounts作为外键的表。 (如果不正确的假设,请告知我。)

为了获取所需的数据,您可能必须编写如下查询:

FbGroup
  .joins(replier_fb_groups: : replier_accounts)
  .where("replier_accounts.active = true AND replier_fb_groups.removed_on IS NULL")
  .group("fb_groups.id")
  .having("count(replier_accounts) > 0")

在这里,如果您仔细地注意到联接,我们将join on a nested association用作.joins(replier_fb_groups: : replier_accounts),而不是将FbGroups with multiple tables的联接独立地称为.joins(:replier_fb_groups, : replier_accounts)

注意:可以通过使用merge合并来自replier_accountsreplier_fb_groups的条件来进一步增强此功能。就像这样:

FbGroup
  .joins(replier_fb_groups: : replier_accounts)
  .merge(ReplierAccount.active)
  .merge(ReplierFbGroup.not_removed)
  .group("fb_groups.id")
  .having("count(replier_accounts) > 0")

其中ReplierAccount.activeReplierFbGroup.not_removed是各自模型上分别应用活动条件和未移除条件的范围。