Rails 3 - 使用“包含”进行选择?

发布于 2024-09-29 20:16:18 字数 351 浏览 4 评论 0原文

这是一个带有 include 的嵌套选择:

@items = Item.where("complete = ?", true).includes( :manufacturer, {:order=>[:supplier, :agent] })

这是一个繁重的查询,因为它从上述所有包含的表中提取 1000 行数据。

如何让查询只选择特定字段?

  • user.name, user.created_at
  • order.created_at
  • 供应商.name
  • 代理.name
  • 制造商.name

Here is a nested select with include:

@items = Item.where("complete = ?", true).includes( :manufacturer, {:order=>[:supplier, :agent] })

This is a taxing query as it pulls 1000s of rows of data from all the above included tables.

How can I get the query to only select specific fields?

  • user.name, user.created_at
  • order.created_at
  • supplier.name
  • agent.name
  • manufacturer.name

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

木格 2024-10-06 20:16:18

ARel 中有一个 select 方法,但您必须使用正确的表名称(即复数,并且如果您有多态模型或者您正在使用 set_table_name 或其他类似的非标准实践,请注意)

@items = Item.
  select('users.name', 'users.created_at', 'orders.created_at', 'suppliers.name', 'agents.name', 'manufacturers.name').
  where(:users => { :fulfilled => true }).
  includes(:orders => [:supplier, :agent], :manufacturer)

“我们可以将 select 与联接一起使用,而不是包含” - @Bhavesh_A_P

注意:

正如 @Bhavesh_A_P 上面指出的,带有 includesselect 不会产生一致的行为。看来,如果包含的关联没有返回结果,select将正常工作,如果返回结果,则select语句将不起作用。事实上,它将被完全忽略,这样您的 select 语句就可以引用无效的表名,并且不会产生错误。 selectjoins 将产生一致的行为。

There is a select method in ARel, but you must use the correct table names (i.e. plural and beware if you have polymorphic models or if you're using set_table_name or some other similar non-standard practice)

@items = Item.
  select('users.name', 'users.created_at', 'orders.created_at', 'suppliers.name', 'agents.name', 'manufacturers.name').
  where(:users => { :fulfilled => true }).
  includes(:orders => [:supplier, :agent], :manufacturer)

"We can use select with joins not includes" - @Bhavesh_A_P

Note:

As @Bhavesh_A_P pointed out above, select with includes does not produce consistent behavior. It appears that if the included association returns no results, select will work properly, if it returns results, the select statement will have no effect. In fact, it will be completely ignored, such that your select statement could reference invalid table names and no error would be produced. select with joins will produce consistent behavior.

转角预定愛 2024-10-06 20:16:18

实际上我们不能将 select 与 include 一起使用。它只能与连接一起使用。

Actually we can't use select with includes. It can only be used with joins.

半窗疏影 2024-10-06 20:16:18

通过在链中调用“select”方法并不能解决该问题。在我们构建的类似 ActiveRecord::Relation 中,调用“includes”似乎会覆盖对“select”的任何调用。

scope :active, where("hired_on < ? AND (separated_on > ? OR separated_on IS NULL)", Time.now, Time.now )

scope :with_role, lambda {|roles| includes(:team_member_roles).where(:team_member_roles => {:role => roles } ) }

scope :with_site_code, lambda {|site_codes| includes(:team_member_sites).where(:team_member_sites => {:site_code => site_codes } ) }

TeamMember.select("team_members.email, team_members.first_name, team_members.last_name").active.with_site_code(params[:site_code]).with_role(["senior_editing", "senior_and_reg_editing"]) 

如图所示,查询选择所有列。

当 2 个范围使用“joins”而不是“includes”时,查询将起作用:仅选择 3 个指定的列。

The problem is not solved by including a call to the 'select' method in the chain. In a similar ActiveRecord::Relation we built, calling 'includes' seems to override any call to 'select'.

scope :active, where("hired_on < ? AND (separated_on > ? OR separated_on IS NULL)", Time.now, Time.now )

scope :with_role, lambda {|roles| includes(:team_member_roles).where(:team_member_roles => {:role => roles } ) }

scope :with_site_code, lambda {|site_codes| includes(:team_member_sites).where(:team_member_sites => {:site_code => site_codes } ) }

TeamMember.select("team_members.email, team_members.first_name, team_members.last_name").active.with_site_code(params[:site_code]).with_role(["senior_editing", "senior_and_reg_editing"]) 

As shown, the query selects all columns.

When the 2 scopes use 'joins' instead of 'includes', the query works: only the 3 specified columns are selected.

风渺 2024-10-06 20:16:18
Item.where("fulfilled = ?", true)
    .includes({:orders =>[:suppliers, :agents]}, :manufacturers)
    .select("users.name, users.created_at, orders.created_at, suppliers.name, agents.name").
    .order('orders.created_at DESC')
Item.where("fulfilled = ?", true)
    .includes({:orders =>[:suppliers, :agents]}, :manufacturers)
    .select("users.name, users.created_at, orders.created_at, suppliers.name, agents.name").
    .order('orders.created_at DESC')
遥远的绿洲 2024-10-06 20:16:18

正如其他人所指出的,如果存在 .includes(...),则使用 .select(...) 会被覆盖。我不喜欢这样......所以我找到了一个补丁来使其工作并将其作为 砖块

通过覆盖 ActiveRecord::Associations::JoinDependency.apply_column_aliases() 像这样,然后当您添加 .select(...) 时,它可以充当过滤器来选择哪个列别名被构建出来。

加载 gem 'brick' 后,为了启用此选择性行为,请将特殊列名称 :_brick_eager_load 添加为 .select(.. .),这会在构建别名时打开列过滤。下面是一个示例:

Employee.includes(orders: :order_details)
        .references(orders: :order_details)
        .select(:_brick_eager_load,
                'employees.first_name', 'orders.order_date', 'order_details.product_id')

由于外键对于正确关联所有内容至关重要,因此它们会自动添加,因此您无需将它们包含在选择列表中。

希望它可以节省您的查询时间和一些内存!

As other people have noted, using .select(...) gets overridden if there's an .includes(...). And I didn't like that ... so I figured out a patch to make it work and released it as a part of The Brick.

By overriding ActiveRecord::Associations::JoinDependency.apply_column_aliases() like this then when you add a .select(...) then it can act as a filter to choose which column aliases get built out.

With gem 'brick' loaded, in order to enable this selective behaviour, add the special column name :_brick_eager_load as the first entry in your .select(...), which turns on the filtering of columns while the aliases are being built out. Here's an example:

Employee.includes(orders: :order_details)
        .references(orders: :order_details)
        .select(:_brick_eager_load,
                'employees.first_name', 'orders.order_date', 'order_details.product_id')

Because foreign keys are essential to have everything be properly associated, they are automatically added, so you do not need to include them in your select list.

Hope it can save you both query time and some RAM!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文