如何用Arel实现返回ActiveRelation的带最高价格水果查询Scope
实现带最高价格的Fruit查询Scope
需求说明
需要实现一个查询Scope,获取符合条件的水果数据时附带当前结果集的最高价格,示例调用:
Fruit.with_max_price.where("date > '2022'")
约束条件
- 必须使用Arel构建查询
- 实现为返回ActiveRelation的Scope,支持链式调用
已知表结构
| id | name | price |
|---|---|---|
| 1 | apple | 12 |
| 2 | banana | 6 |
| 3 | orange | 18 |
期望输出
| id | name | price | max_price |
|---|---|---|---|
| 1 | apple | 12 | 18 |
| 2 | banana | 6 | 18 |
| 3 | orange | 18 | 18 |
解决方案
在Fruit模型中添加以下Scope实现:
class Fruit < ApplicationRecord scope :with_max_price, -> do fruits_table = arel_table max_price_subquery = fruits_table.project(fruits_table[:price].maximum.as('max_price')) select( fruits_table[Arel.star], Arel.sql("(#{max_price_subquery.to_sql}) AS max_price") ) end end
代码说明
- Arel表实例:通过
arel_table获取Fruits表的Arel对象,避免硬写SQL字段名,提升查询安全性。 - 动态最高价格子查询:子查询会自动继承当前查询链中的所有条件(比如后续的
where过滤),计算出对应结果集的最高价格。 - 合并字段返回:使用
select将原表所有字段和子查询的最高价格字段合并,返回的ActiveRelation可以继续链式调用其他查询方法。
验证
执行示例调用后,返回的每条记录都会包含max_price字段,值为当前结果集中的最高价格,与期望输出一致。
内容的提问来源于stack exchange,提问作者Quentin Gaultier
相关产品推荐
相关产品推荐

