查询 rails 中的深层嵌套关系

Query deeply nested relations in rails

我们在模型中有很多直通关系。 Rails 正确地加入了关系,但是我正在努力弄清楚如何使用活动记录将位置搜索应用于加入的 table。

例如:

class Model
  has_one :relation1
  has_one :relation2, through: :relation1
  has_one :relation3, through: :relation2
end

如果所有关系都是不同的模型,我们很容易使用where进行查询。出现问题 rails 开始为模型设置别名。

例如,Model.joins(:relation3).where(relation3: {name: "Hello"}) 将不起作用,因为没有 table 是别名关系 3.

是否可以使用活动记录,或者我是否必须使用 arel 或 sql 来实现它?

我正在使用 rails 6.0.4.

在一个简单的查询中,table 仅在没有别名且仅使用 table 名称时被引用:

irb(main):023:0> puts City.joins(:country).where(countries: { name: 'Portugal'})
City Load (0.7ms)  SELECT "cities".* FROM "cities" INNER JOIN "regions" ON "regions"."id" = "cities"."region_id" INNER JOIN "countries" ON "countries"."id" = "regions"."country_id" WHERE "countries"."name" =   [["name", "Portugal"]] 

在更复杂的情况下,table 被引用的次数比一旦方案似乎是 association_name_table_nameassociation_name_table_name_join.

class Pet < ApplicationRecord
  has_many :parenthoods_as_parent, 
    class_name: 'Parenthood',
    foreign_key: :parent_id
  has_many :parenthoods_as_child, 
    class_name: 'Parenthood',
    foreign_key: :child_id
  has_many :parents, through: :parenthoods_as_child
  has_many :children, through: :parenthoods_as_child
end

class Parenthood < ApplicationRecord
  belongs_to :parent, class_name: 'Pet'
  belongs_to :child, class_name: 'Pet'
end
irb(main):014:0> puts Pet.joins(:parents, :children).to_sql
# auto-formatted edited for readibility
SELECT "pets".*
FROM   "pets"
       INNER JOIN "parenthoods"
               ON "parenthoods"."child_id" = "pets"."id"
       INNER JOIN "pets" "parents_pets"
               ON "parents_pets"."id" = "parenthoods"."parent_id"
       INNER JOIN "parenthoods" "parenthoods_as_children_pets_join"
               ON "parenthoods_as_children_pets_join"."child_id" = "pets"."id"
       INNER JOIN "pets" "children_pets"
               ON "children_pets"."id" =
"parenthoods_as_children_pets_join"."child_id" 

对于更高级的查询,如果您需要可靠地知道所使用的别名,您通常需要自己编写与 Arel 或字符串的连接。