简体   繁体   English

急切加载一个关联但只有一个列

[英]Eager-load an association but ONLY a single column

I have a self-referential association like this:我有一个这样的自我参照协会:

class User
  belongs_to :parent_user, class_name: "User"
  has_many :child_users, class_name: "User", foreign_key: :parent_user_id
end

When I get a list of users, I would like to be able to eager-load the child_users association, but I only need the id column from it.当我获得用户列表时,我希望能够预先加载child_users关联,但我只需要其中的id列。 I need to be able to do something like this without causing n+1 queries, and preferably without having to load all of the other data in this model:我需要能够在不引起 n+1 次查询的情况下执行类似的操作,并且最好不必加载此 model 中的所有其他数据:

users = User.preload(:child_users)
users.map(&:child_user_ids)

The above works to limit the query to two queries instead of n+1, but I'm loading a lot of full objects into memory that I would prefer to avoid when I only care about the id itself on those child assocations.上面的工作是将查询限制为两个查询而不是 n+1,但是我将很多完整的对象加载到 memory 中,当我只关心那些子关联上的id本身时,我希望避免这种情况。

You don't want eager loading which is for loading models.您不希望用于加载模型的预加载。 You want to select an aggregate.你想要 select 一个聚合。 This isn't something the ActiveRecord query interface handles so you'll need to use SQL strings or Arel and use the correct function for your DB.这不是 ActiveRecord 查询接口处理的内容,因此您需要使用 SQL 字符串或 Arel,并为您的数据库使用正确的 function。

For example:例如:

# This is for Postgres, use JSON_ARRAYAGG on MySQL
User.left_joins(:child_users)
    .select(
      "users.*",
      'json_agg("child_users_users".id) AS child_ids'
    )
    .group(:id)

child_users_users is the wonky alias that .left_joins(:child_users) creates. child_users_users.left_joins(:child_users)创建的奇怪别名。

At least on Postgres the driver (the PG gem) will automatically cast the result to a an array but YMMV on the other dbs.至少在 Postgres 上,驱动程序(PG gem)会自动将结果转换为数组,但在其他数据库上为 YMMV。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM