活动记录关联(has_one) - 访问父对象


class Parent < ApplicationRecord
has_one: child
end

class Child < ApplicationRecord
belongs_to :parent
end

childrens = Child.includes(:parent)
puts childrens.to_json
[{"id":1,"parent_id":1,"name":"Jack"},{"id":2,"parent_id":2,"name":"Oleg"}]

在这种情况下,我们可以像这样访问父对象:child.parent

但是无法访问视图中的父对象。 有没有办法在每个子对象中包含父对象?

谢谢!

您可以将as_jsoninclude选项一起使用来获取每个子父级:

Child.includes(:parent).as_json(include: :parent)

为此,您会收到几个查询。一个给孩子,另一个给每个孩子父母(IN条款(:

Child Load (1.0ms)  SELECT "children".* FROM "children"
Parent Load (1.2ms)  SELECT "parents".* FROM "parents" WHERE "parents"."id" IN ($1, $2)  [["id", 1], ["id", 2]]

您可以限制从数据库中检索的列(使用select(以及 JSON 对象中的每个对象(不应用 SQL 筛选器(。

你对includes有点混淆。这将不包括对象,但会在需要时准备它们。

因为您在ParentChild之间有关联,所以您已经可以查看父项,但这将为每个子项请求父项,因此您将在 n+1 个查询中运行。

把它放在代码中:

Child.all.each { |c| c.parent }; nil

将触发:

Parent Load (0.2ms)  SELECT  "parents".* FROM "parents" WHERE "parents"."id" = $1 LIMIT 1   [["id", 4750516]]
Parent Load (0.2ms)  SELECT  "parents".* FROM "parents" WHERE "parents"."id" = $1 LIMIT 1   [["id", 4772539]]
Parent Load (0.1ms)  SELECT  "parents".* FROM "parents" WHERE "parents"."id" = $1 LIMIT 1   [["id", 4806512]]

你在那里做什么包括,将使它看起来像:

SELECT "children".* FROM "children"
Parent Load (3.3ms)  SELECT "parents".* FROM "parents" WHERE "parents"."id" IN (4750516, 4772539, 4806512)

因此,如果您想在视图中使用它,您实际上会拥有类似@childrens的东西,所以不要害怕迭代并调用.parent

您可以在此处阅读有关预先加载的更多信息

Child.includes(:parent).as_json(include: :parent)

这对我有帮助!

最新更新