在自联接表中的两个外键之间搜索的查询

xjreopfe  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(381)

用户表中的示例数据

rails控制台中的预期结果, father.childrenmother.children 应返回相同的对象组:

father = User.first
father.children
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 3, name: "son", father_id: 1, mother_id: 2>, #<User id: 4, name: "daughter", father_id: 1, mother_id: 2>]>
mother = User.find(2)
mother.children
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 3, name: "son", father_id: 1, mother_id: 2>, #<User id: 4, name: "daughter", father_id: 1, mother_id: 2>]>

这是我现在在user.rb模型中的关联。如果我这样做,它将返回预期结果 father.children 因为外键是指 father_id . 但这对我来说不起作用 mother.children 因为它没有提到 mother_id .

has_many :children, foreign_key: "father_id", class_name: "User"
 belongs_to :mother, class_name: "User", optional: true
 belongs_to :father, class_name: "User", optional: true

我有办法吗

foreign key: "father_id" OR "mother_id"

我也试着在协会里提问,但似乎无法理解。

has_many :children, -> { where("father_id = id OR mother_id = id") }, class_name: "User"
dohp0rv5

dohp0rv51#

您可以取消对查询创建的默认行的作用域,然后使用用户id筛选子行:

has_many :children,
  ->(user) { unscope(:where).where('father_id = :id OR mother_id = :id', id: user.id) },
  class_name: "User"

为什么? unscope ? 如果不删除它,您的代码将产生如下两个sql查询:

SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
SELECT "users".* FROM "users" WHERE "users"."user_id" = ? AND "users"."father_id" = ?  [["user_id", 1], ["father_id", "1"]]

当做 User.first.children -至少在rails 6.1.4中。
如您所见,第二个查询过滤所有具有 id 等于接收器(1),同时具有 father_id 列等于接收器(1)。看看你的代码,这可能永远不会发生。
请注意,如果在声明 has_many 在关系中,最好使用单示例方法或范围(在最后一种情况下)。因为使用这种方法,您将覆盖默认行为(无文档记录),即通过此表中的主键过滤另一个表中的行。

相关问题