You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中Arel使用疑问:查询结果如何使用及代码编写位置

嘿,刚接触Arel的时候确实容易搞不清它和ActiveRecord的配合方式,我来帮你拆解这两个问题~

一、怎么执行Arel生成的查询并拿到结果

你写的这段代码:

users = Arel::Table.new(:users)
users.where(users[:name].eq('amy'))

返回的是Arel的关系代数对象,它只是描述了要执行的SQL逻辑,但还没和ActiveRecord的执行机制挂钩,所以不会直接查询数据库。要拿到实际的用户数据,有几种常用方法:

  • 方法1:结合ActiveRecord的from方法
    把Arel生成的查询作为数据源传给模型的from,这样就能得到ActiveRecord::Relation对象,之后调用all、first、each这些方法就能执行查询了:
users = Arel::Table.new(:users)
arel_query = users.where(users[:name].eq('amy'))
@users = User.from(arel_query).all # 执行查询并返回用户实例数组
  • 方法2:用find_by_sql直接执行SQL字符串
    先把Arel对象转成SQL字符串,再用ActiveRecord的find_by_sql执行:
users = Arel::Table.new(:users)
sql = users.where(users[:name].eq('amy')).to_sql
@users = User.find_by_sql(sql)
  • 方法3:直接把Arel条件传给ActiveRecord的where
    其实更简单的方式是,直接把Arel的条件表达式传给模型的where方法,ActiveRecord会自动识别并处理:
users = Arel::Table.new(:users)
@users = User.where(users[:name].eq('amy')).all

这样得到的也是ActiveRecord::Relation,和你平时用的User.where(name: 'amy')用法完全一致,能链式调用其他查询方法。

二、Arel代码应该写在什么地方?

遵循MVC的设计原则,推荐按以下优先级放置:

  • 模型层(最推荐)
    查询逻辑属于业务逻辑的一部分,封装在模型里能提高复用性,也让控制器和视图保持简洁。比如在User模型里封装一个类方法:
class User < ApplicationRecord
  def self.search_by_name(name)
    users_table = Arel::Table.new(:users)
    where(users_table[:name].eq(name))
  end
end

之后在控制器里直接调用User.search_by_name('amy')就行,后续如果要修改查询逻辑,只需要改模型里的方法。

  • 控制器层(仅临时简单查询)
    如果是一次性的、简单的Arel查询,也可以写在控制器里,但别把复杂逻辑堆在这里,不然控制器会变得臃肿难维护。比如:
class UsersController < ApplicationController
  def index
    users_table = Arel::Table.new(:users)
    @users = User.where(users_table[:name].eq('amy')).all
  end
end
  • 视图层(绝对不推荐)
    视图的职责是展示数据,绝对不要在这里写Arel查询逻辑,会让代码耦合度极高,后续维护起来会非常痛苦。

另外补充一句:既然你是因为Ransack接触Arel,其实Ransack已经帮你封装了大部分复杂的Arel逻辑,日常开发中如果不是遇到ActiveRecord无法表达的复杂查询(比如多表关联的复杂过滤、自定义SQL函数的组合),可能不需要直接写Arel,先试试Ransack的内置功能或者ActiveRecord的查询接口会更高效~

内容的提问来源于stack exchange,提问作者beginnersquestions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:35:13