ruby-on-rails - #<Arel::Nodes::SqlLiteral> 没有方法错误 'map'

标签 ruby-on-rails ruby activerecord arel

我有以下示例查询:

source = "(SELECT DISTINCT source.* FROM (SELECT * FROM items) AS source) AS items"
items = Item.select("items.*").from(source).includes([:images])
p items # [#<Item id: 1>, #<Item id:2>]

然而运行:

p items.count 

NoMethodError: undefined methodmap' for Arel::Nodes::SqlLiteral` 的结果

我很欣赏这个查询很愚蠢,但是非简化查询有点太复杂而无法复制,这是我能创建的最小的崩溃版本。有什么想法吗?

最佳答案

您能否对该对象调用 all 以将其转换为数组?

Item.select("items.*").from(source).includes([:images]).all.count

或者在那种情况下,size 可能更合适。在任何情况下,这都会执行查询并将所有对象加载到内存中,这可能是不可取的。


看起来问题出在您的 includes([:images]) 上。在类似的应用程序上,我可以从控制台执行此操作:

> Category.select('categories.*').from('(SELECT DISTINCT source.* FROM (SELECT * FROM categories) AS source) AS categories').count
  (0.5ms)  SELECT COUNT(*) FROM (SELECT DISTINCT source.* FROM (SELECT * FROM categories) AS source) AS categories

(请注意,count 覆盖了 SELECT 子句,即使我明确指定了 items.*。但它们仍然是等效查询。)

一旦我添加了一个 includes 作用域,它就失败了:

> Category.select('categories.*').from('(SELECT DISTINCT source.* FROM (SELECT * FROM categories) AS source) AS categories').includes(:projects).count
NoMethodError: undefined method `left' for #<Arel::Nodes::SqlLiteral:0x131d35248>

我尝试了几种不同的获取计数的方法,比如 select('COUNT(categories.*)'),但它们都以各种方式失败了。 ActiveRecord 似乎退回到基本的 LEFT OUTER JOIN 来执行预加载,可能是因为它认为您正在使用某种条件或外部表来执行连接,这似乎混淆了它执行计数的正常方法.请参阅 ActiveRecord::Associations docs 中关于预加载部分的结尾。 .

我的建议

如果连接不影响外部查询中返回的行数,我认为最好的办法是执行一个查询来获取计数,再执行一个查询来获取实际结果。我们必须在我们的分页应用程序中做类似的事情:一个查询返回当前结果页,一个返回符合过滤条件的记录总数。

关于ruby-on-rails - #<Arel::Nodes::SqlLiteral> 没有方法错误 'map',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9304587/

相关文章:

ruby-on-rails - ActiveStorage 变体组合

ruby - 正确使用Sequel的save()?如何创建新记录或更新现有记录?

sql - 使用 ActiveRecord 为多对多查询设置条件

php - 坚持使用 PHP 还是学习 Go-lang?

design-patterns - Active Records vs. Repository - 优缺点?

ruby-on-rails - 将 Rails 中的主键更改为字符串

ruby-on-rails - Bundle exec rubocop 在 Github Actions 上失败但在本地成功运行

mysql - 使用 MySQL 而不是 SQLite 创建一个新的 Ruby on Rails 应用程序

ruby-on-rails - 嵌套属性错误 : no implicit conversion of String into Integer

部署前进行 Ruby gem 测试