如何检查 rails 中 where 语句的空关联?
How can I check for an empty association with a where statement in rails?
我有一个名为 Category 的模型,它可以有很多子类别(也是类别记录)。我想收集数据库中没有子类别的所有类别,例如:
Category.where(subcategories: [])
但我尝试过的每个 [对我来说] 直观的变体都会抛出错误或 returns 一个空集。它生成了一些我不太明白的 SQL:
Category Load (0.5ms) SELECT "categories".* FROM "categories" WHERE 1=0
=> #<ActiveRecord::Relation []>
谁能告诉我正确的方法吗?
编辑:这是定义子类别关系的方式
class Category < ActiveRecord::Base
has_many :subcategories, class_name: 'Category', foreign_key: 'parent_id'
belongs_to :parent, class_name: 'Category'
end
怎么样
Category.where("id NOT IN (?)", Subcategory.pluck(:category_id))
这里的问题是您不能在 .where
子句中直接查询关联。您只能处理实际的列名。所以我在这里做了一个快速子查询,你可以在其中获取在子类别 table 中列为关联的类别 ID,然后查询不在该列表中的所有类别。
试试这个:
Category.joins(:subcategories).where(subcategories: {parent_id: nil})
或
Category.includes(:subcategories).where('subcategories.parent_id IS NULL')
好的,解决了。我只需要调整 Sharvy 的建议(我忘记的一件大事是添加 "joins")。
以下有效:
Category.includes(:subcategories).where(subcategories: nil)
更新 2: 好的,这次我 真的 让它工作了(很确定,至少......)。我不得不使用一些丑陋的 SQL 而不是一些漂亮的 ActiveRecord 语法,但以下似乎可以满足我的要求:
Category.joins("LEFT JOIN categories AS subcategories ON subcategories.parent_id = categories.id").where("subcategories IS NULL")
更新 1: 抱歉,没关系,这不起作用。正如我在下面评论的那样,我跳了枪,因为我看到这个查询返回了 where(... nil)
和 where.not(... nil)
的正确类别计数,但实际上并没有返回正确的类别。它返回所有没有父类别的类别,而不是没有任何子类别的所有类别。
下面是这个查询的一些示例输出:
Category.includes(:subcategories).where(subcategories: nil).last
Category Load (0.7ms) SELECT "categories".* FROM "categories" WHERE "categories"."parent_id" IS NULL ORDER BY "categories"."id" DESC LIMIT 1
Category Load (0.5ms) SELECT "categories".* FROM "categories" WHERE "categories"."parent_id" IN (3158)
=> #<Category id: 3158, name: "A parent", parent_id: nil, created_at: "2015-03-23 19:18:40", updated_at: "2015-03-23 19:18:40", operator_id: nil>
我有一个名为 Category 的模型,它可以有很多子类别(也是类别记录)。我想收集数据库中没有子类别的所有类别,例如:
Category.where(subcategories: [])
但我尝试过的每个 [对我来说] 直观的变体都会抛出错误或 returns 一个空集。它生成了一些我不太明白的 SQL:
Category Load (0.5ms) SELECT "categories".* FROM "categories" WHERE 1=0
=> #<ActiveRecord::Relation []>
谁能告诉我正确的方法吗?
编辑:这是定义子类别关系的方式
class Category < ActiveRecord::Base
has_many :subcategories, class_name: 'Category', foreign_key: 'parent_id'
belongs_to :parent, class_name: 'Category'
end
怎么样
Category.where("id NOT IN (?)", Subcategory.pluck(:category_id))
这里的问题是您不能在 .where
子句中直接查询关联。您只能处理实际的列名。所以我在这里做了一个快速子查询,你可以在其中获取在子类别 table 中列为关联的类别 ID,然后查询不在该列表中的所有类别。
试试这个:
Category.joins(:subcategories).where(subcategories: {parent_id: nil})
或
Category.includes(:subcategories).where('subcategories.parent_id IS NULL')
好的,解决了。我只需要调整 Sharvy 的建议(我忘记的一件大事是添加 "joins")。
以下有效:
Category.includes(:subcategories).where(subcategories: nil)
更新 2: 好的,这次我 真的 让它工作了(很确定,至少......)。我不得不使用一些丑陋的 SQL 而不是一些漂亮的 ActiveRecord 语法,但以下似乎可以满足我的要求:
Category.joins("LEFT JOIN categories AS subcategories ON subcategories.parent_id = categories.id").where("subcategories IS NULL")
更新 1: 抱歉,没关系,这不起作用。正如我在下面评论的那样,我跳了枪,因为我看到这个查询返回了 where(... nil)
和 where.not(... nil)
的正确类别计数,但实际上并没有返回正确的类别。它返回所有没有父类别的类别,而不是没有任何子类别的所有类别。
下面是这个查询的一些示例输出:
Category.includes(:subcategories).where(subcategories: nil).last
Category Load (0.7ms) SELECT "categories".* FROM "categories" WHERE "categories"."parent_id" IS NULL ORDER BY "categories"."id" DESC LIMIT 1
Category Load (0.5ms) SELECT "categories".* FROM "categories" WHERE "categories"."parent_id" IN (3158)
=> #<Category id: 3158, name: "A parent", parent_id: nil, created_at: "2015-03-23 19:18:40", updated_at: "2015-03-23 19:18:40", operator_id: nil>