【发布时间】:2016-08-27 04:26:56
【问题描述】:
我正在尝试实现一个应该返回ActiveRecord 关系的库函数。复杂的 SQL 查询使用Arel 完成。它必须在多个数据库后端上工作,因此原始 SQL 查询是最后的手段。
简化示例:
Spree::Product < ActiveRecord::Base
end
prod_at = Spree::Product.arel_table
# select record's ids by Arel attribute
> Spree::Product.select(prod_at[:id])
Spree::Product Load (0.9ms) SELECT "spree_products"."id" FROM
"spree_products" WHERE "spree_products"."deleted_at" IS NULL
=> #<ActiveRecord::Relation [#<Spree::Product id: 14>, #<Spree…
# previous call converted to SQL, generates correct query
> Spree::Product.select(prod_at[:id]).to_sql
SELECT "spree_products"."id" FROM "spree_products" WHERE
"spree_products"."deleted_at" IS NULL
# Surprisingly, applying ActiveRecord::Calculations.count fails
> Spree::Product.select(prod_at[:id]).count
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error
at or near "Arel"
LINE 1: SELECT COUNT(#<struct Arel::Attributes::Attribute relation=#...
^
: SELECT COUNT(#<struct Arel::Attributes::Attribute relation=#<
Arel::Table:0x00000007553f50 @name="spree_products",
@engine=Spree::Product(id: integer, …
看起来.count 方法没有将嵌入的 Arel 表达式展开为 SQL
并按原样传递。
更令人惊讶的是,来自 ActiveRecord::Calculations 的其他方法可以正常工作,
甚至可以媲美.calculate:
> Spree::Product.select(prod_at[:id]).calculate(:count, :id)
(0.5ms) SELECT COUNT("spree_products"."id") FROM "spree_products" WHERE
"spree_products"."deleted_at" IS NULL
=> 1253
知道我做错了什么吗?
如何调整 Arel 对象以使其也与 count 方法一起使用?一些解决方法?
我必须返回ActiveRecord_Relation。受影响的计数方法是从其他无法直接修改的 3rd 方模块调用的。
【问题讨论】:
-
Spree::Product.select(prod_at[:id]).size? -
@МалъСкрылевъ 不幸的是,这不是一个选择。如问题中所述,我无法更改返回的关系对象的使用方式。
标签: sql ruby-on-rails ruby arel