【问题标题】:Arel and ActiveRecord's count throws errorArel 和 ActiveRecord 的计数抛出错误
【发布时间】: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


【解决方案1】:

你可以这样做:

第一个通过 ActiveRecord 生成 SQL 查询,第二个将查询转换为 Ruby 数组并计算其大小。

不确定哪个是首选,但我认为它是第一个,因为它坚持 Rails 的方法。

尽管如此,值得注意的是两者都返回类型Integer。我不知道如何使它返回类型ActiveRecord_Relation,这似乎是您正在寻找的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多