【问题标题】:to_sql on arel doesn't work every timearel 上的 to_sql 并非每次都有效
【发布时间】:2014-09-16 12:48:42
【问题描述】:

我正在尝试在我的应用程序中集成名为 slim_scrooge 的 gem,但我不断遇到一些奇怪的问题,即出现以下错误

NoMethodError:未定义的方法reverse' for nil:NilClass from /Users/ratatouille/.rvm/gems/ruby-1.9.3-p547@minerva/gems/activerecord-3.2.10/lib/active_record/connection_adapters/abstract/database_statements.rb:11:inblock in to_sql'

经过仔细调试,我发现错误是在 arel 上的 .to_sql 上产生的。

为了找到我在这个line上添加断点的原因

然后我发现了这个

## 首次运行

Performer.find(1985)

 From: /Users/Ratatouille/.rvm/gems/ruby-1.9.3-p547@minerva/gems/activerecord-3.2.10/lib/active_record/relation.rb @ line 171 ActiveRecord::Relation#exec_queries:

    166: 
    167:       default_scoped = with_default_scope
    168: 
    169:       if default_scoped.equal?(self)
    170:         @records = if @readonly_value.nil? && !@klass.locking_enabled?
 => 171:           binding.pry
    172:           eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
    173:         else
    174:           IdentityMap.without do
    175:             eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
    176:           end

[1] pry(#<ActiveRecord::Relation>)> arel.to_sql
=> "SELECT  `performers`.* FROM `performers`  WHERE `performers`.`id` = ? LIMIT 1"

## 第二次运行同一记录

Performer.find(1985)

From: /Users/ratatouille/.rvm/gems/ruby-1.9.3-p547@minerva/gems/activerecord-3.2.10/lib/active_record/relation.rb @ line 171 ActiveRecord::Relation#exec_queries:

    166: 
    167:       default_scoped = with_default_scope
    168: 
    169:       if default_scoped.equal?(self)
    170:         @records = if @readonly_value.nil? && !@klass.locking_enabled?
 => 171:           binding.pry
    172:           eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
    173:         else
    174:           IdentityMap.without do
    175:             eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
    176:           end

[1] pry(#<ActiveRecord::Relation>)> arel.to_sql
NoMethodError: undefined method `reverse' for nil:NilClass
from /Users/ratatouille/.rvm/gems/ruby-1.9.3-p547@minerva/gems/activerecord-3.2.10/lib/active_record/connection_adapters/abstract/database_statements.rb:11:in `block in to_sql'

我很生气,为什么第二次 arel.to_sql 不起作用

任何人都有线索

更多信息 -

  • Rails 3.2.10

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord arel


    【解决方案1】:

    似乎这是 gem 的错误。可以看讨论here

    有两种可能的方法来解决它。

    1. 如果您使用的是query_reviewer gem,请尝试禁用它。

    2. 如果上述步骤不起作用。自己修复active_record的bug。

      ## rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
      
      def to_sql(arel, binds = [])
        if arel.respond_to?(:ast)
          visitor.accept(arel.ast) do
            quote(*binds.shift.reverse) # root cause for the bug
          end
        else
         arel
        end
      end
      

      binds 变量的默认参数在这里是错误的。改成这样

      def to_sql(arel, binds = [[]]) # Added an empty array
      

      检查here 了解如何覆盖rails 模块方法(简单的方法)。或者您可以将您的 gem 部署到本地文件夹并覆盖它们(硬方式)检查 answer 例如。

    仅供参考:您帖子中的错误指向 database_statements.rb:11,但我发现 source 的代码位于第 8 行。找不到您的确切版本。 p>

    【讨论】:

    • 首先为迟到的回复道歉,我非常抱歉,但我正在寻找关于为什么上述错误第二次出现的答案,您上面列出的内容是我已经知道的
    • 我似乎也不明白你为什么提到这个def to_sql(arel, binds = [[]]),因为在代码部分提到@bind_values(对不起,如果不清楚)总是传递给sql,所以他们永远不会采用默认值的情况
    • 无论如何,我仍然会奖励你赏金,因为我没有看到任何人在赏金结束前不到 2 小时内回答这个问题,最好奖励而不是浪费,因为我没有得到无论如何都要回到我的帐户,但由于上述原因,我仍然不接受答案,请不要误会我的意思
    • @Ratatouille 我不会认为这是理所当然的。你可以为这个项目创建一个 git repo 吗?或者至少有一个要点(包括 Gemfile)来重现这个错误
    • 您可以在任何应用程序中试用,只需在其中包含slim_scroogegem 您的Gemfile
    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    相关资源
    最近更新 更多