查询 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_name
和 association_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 或字符串的连接。
我们在模型中有很多直通关系。 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_name
和 association_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 或字符串的连接。