如何在Arel中创建和使用不与列绑定的Arel::Nodes::Function函数
问题原因
Arel::Nodes::Function 是Arel提供的抽象基类,设计上仅作为各类SQL函数节点的公共父类使用,Arel的SQL序列化访问器没有为该基类实现对应的处理逻辑,直接实例化调用就会抛出TypeError (Cannot visit Arel::Nodes::Function)错误。
正确使用方式
日常场景下直接使用它的子类Arel::Nodes::NamedFunction即可,不需要绑定特定属性,无参函数给第二个参数传空数组就行:
fn = Arel::Nodes::NamedFunction.new("NOW", []) memberships = Arel::Table.new("memberships") memberships.project(Arel.star).where( memberships[:expires].lt(fn) )
运行后生成的SQL就是你需要的:
SELECT * FROM "memberships" WHERE "memberships"."expires" < NOW()
如果确实需要基于Arel::Nodes::Function做自定义扩展,需要自行实现子类并给对应数据库的访问器注册处理逻辑,适合高频复用自定义函数的场景:
# 自定义函数子类 class NowFunction < Arel::Nodes::Function end # 给对应数据库的Arel访问器注册处理方法,此处以PostgreSQL为例 Arel::Visitors::PostgreSQL.class_eval do def visit_Arel_Nodes_NowFunction(o, collector) collector << "NOW()" end end # 调用自定义函数 fn = NowFunction.new memberships = Arel::Table.new("memberships") memberships.project(Arel.star).where(memberships[:expires].lt(fn))
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

