【问题标题】:ActiveRecord - find records that its association count is 0ActiveRecord - 查找关联计数为 0 的记录
【发布时间】:2017-07-19 21:36:45
【问题描述】:

在我的 Ruby on Rails 应用程序中,我有以下模型:

class SlideGroup < ApplicationRecord
  has_many :survey_group_lists, foreign_key: 'group_id'
  has_many :surveys, through: :survey_group_lists
end

我想查找所有孤立的幻灯片组。孤立幻灯片组是未连接到任何调查的幻灯片组。我一直在尝试以下查询,但它没有返回任何内容,我确定我的测试数据库中有孤立记录:

SlideGroup.joins(:surveys).group("slide_groups.id, surveys.id").having("count(surveys.id) = ?",0)

这会生成以下 sql 查询:

SlideGroup Load (9.3ms)  SELECT "slide_groups".* FROM "slide_groups" INNER JOIN "survey_group_lists" ON "survey_group_lists"."group_id" = "slide_groups"."id" INNER JOIN "surveys" ON "surveys"."id" = "survey_group_lists"."survey_id" GROUP BY slide_groups.id, surveys.id HAVING (count(surveys.id) = 0)

【问题讨论】:

  • 这里需要outer join,因为inner join 不会返回孤儿。

标签: ruby-on-rails ruby postgresql activerecord


【解决方案1】:

您使用的是joins,即INNER JOIN,而您需要的是OUTER JOIN - includes:

SlideGroup.includes(:surveys).group("slide_groups.id, surveys.id").having("count(surveys.id) = ?",0)

更简洁的查询:

SlideGroup.includes(:surveys).where(surveys: { id: nil })

【讨论】:

【解决方案2】:

找孤儿记录已经被别人解释过了。

我发现这种方法存在问题:

  • 首先不应该有任何孤儿
  • survey.id 的存在并不能保证Survey 的存在
  • SurveyGroupList 是孤儿怎么办?

因此,正确的解决方案是确保数据库中没有留下孤儿。通过实现正确的逻辑AND 将外键与on delete cascade 添加到数据库中。您还可以将dependent: :destroy 选项添加到您的关联中,但这仅在您在模型上使用#destroy(而不是delete)时才有效,当然如果您直接通过SQL 删除则无效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 2020-08-07
    • 2022-08-20
    相关资源
    最近更新 更多