Ruby on rails 控制器中的Rails异常执行查询实例变量?

Ruby on rails 控制器中的Rails异常执行查询实例变量?,ruby-on-rails,ruby,exception,activerecord,controllers,Ruby On Rails,Ruby,Exception,Activerecord,Controllers,在我的Rails 3.0.11应用程序中,控制器中有非常简单的代码: def index @record = Record.valid # scope around 80,000 records asdfasdfsa # consider this is a typo to raise NameError Exception end 有趣的是,在输入错误时,应用程序似乎在引发异常之前首先查询/执行@record实例变量。查询需要花费将近1分钟的时间来获取记录。所以在浏览器中,页面在进入

在我的Rails 3.0.11应用程序中,控制器中有非常简单的代码:

def index
  @record = Record.valid # scope around 80,000 records
  asdfasdfsa # consider this is a typo to raise NameError Exception
end
有趣的是,在输入错误时,应用程序似乎在引发异常之前首先查询/执行@record实例变量。查询需要花费将近1分钟的时间来获取记录。所以在浏览器中,页面在进入异常模板之前会挂起很长一段时间


如果我用一个局部变量“record”替换@record,查询根本不会发生。有人知道这是怎么回事吗?

这是异常处理代码的副作用

想想你在两个案例中看到的行为

  • 实例变量- 您已将查询分配给控制器的实例变量。然后抛出一个异常,作为异常处理的一部分,rails将调用控制器上的_s,然后强制执行查询,因为默认情况下它会显示所有实例变量

  • 局部变量- 您已将查询分配给控制器的局部变量。在这种情况下,当抛出异常时,本地变量就被丢弃了


  • 我发现在ruby控制台中创建结构的字符串表示可能非常昂贵和/或滥发信息的对象上总是重写到s是一种很好的做法。

    这是异常处理代码的副作用

    想想你在两个案例中看到的行为

  • 实例变量- 您已将查询分配给控制器的实例变量。然后抛出一个异常,作为异常处理的一部分,rails将调用控制器上的_s,然后强制执行查询,因为默认情况下它会显示所有实例变量

  • 局部变量- 您已将查询分配给控制器的局部变量。在这种情况下,当抛出异常时,本地变量就被丢弃了


  • 我发现在ruby控制台中创建结构的字符串表示可能非常昂贵和/或垃圾的对象上总是重写到s是一种很好的做法。

    正如@Khronos指出的,这是由于错误消息和对变量的求值,但这不是为了,而是为了检查

    actiondispatch/middleware/templates/rescues/diagnostic.erb中,它调用
    来显示错误。快速进入irb提供了以下花絮:

    class Object ; def inspect; "foo" ; end ; end
     => nil 
    a=Exception.new(Object)
     => #<Exception: #<Exception:0x10d8a4108>> 
    a.message
     => foo 
    
    类对象;def检查;“福”;结束;结束
    =>零
    a=异常。新建(对象)
    => # 
    a、 信息
    =>foo
    
    因此,我认为@exception.message将在异常上调用inspect,这反过来可能会在控制器上调用inspect。虽然它在inspect期间枚举整个对象,但当它运行到_时,我认为它只会删除对象id的所有内容


    我仍然有点模糊,但它至少与异常和检查有关。

    正如@Khronos指出的,这是由于错误消息和对变量的求值,但这不是为了,而是为了检查

    actiondispatch/middleware/templates/rescues/diagnostic.erb中,它调用
    来显示错误。快速进入irb提供了以下花絮:

    class Object ; def inspect; "foo" ; end ; end
     => nil 
    a=Exception.new(Object)
     => #<Exception: #<Exception:0x10d8a4108>> 
    a.message
     => foo 
    
    类对象;def检查;“福”;结束;结束
    =>零
    a=异常。新建(对象)
    => # 
    a、 信息
    =>foo
    
    因此,我认为@exception.message将在异常上调用inspect,这反过来可能会在控制器上调用inspect。虽然它在inspect期间枚举整个对象,但当它运行到_时,我认为它只会删除对象id的所有内容

    我仍然有点模糊,但它至少与异常和检查有关。

    有关这个问题的详细信息,请参阅我的博客文章。但简而言之:

  • 格式化错误消息时,NameError调用
    inspect
  • inspect
    的默认实现递归调用所有实例变量上的
    inspect
  • 如果长度超过65个字符,NameError将丢弃
    inspect
    的结果
  • 对我们来说,这意味着视图中的一个输入错误导致Rails挂起20分钟,而Ruby构建了一个巨大的20MB字符串,然后将其扔掉
  • 我们花了7个月才拿到一张支票
  • 简而言之,我认为名称错误的行为在Ruby解释器中是一个令人发指的bug。我想不出任何合理的理由来实施这一计划。

    有关这一问题的详细信息,请参阅我的博客文章。但简而言之:

  • 格式化错误消息时,NameError调用
    inspect
  • inspect
    的默认实现递归调用所有实例变量上的
    inspect
  • 如果长度超过65个字符,NameError将丢弃
    inspect
    的结果
  • 对我们来说,这意味着视图中的一个输入错误导致Rails挂起20分钟,而Ruby构建了一个巨大的20MB字符串,然后将其扔掉
  • 我们花了7个月才拿到一张支票

  • 简而言之,我认为名称错误的行为在Ruby解释器中是一个令人发指的bug。我想不出这个实现的合理理由。

    什么是“一个普通变量“record”?我应该称它为局部变量,比如说,我们不使用@record=record.valid,而是将record=record.valid指定给您,您是否可以使用某种异常通知gem?如果没有输入错误,也没有引发异常,它应该仍然挂起很长一段时间,还是在引发异常时挂起的时间更长?(假设您的视图对
    @record
    执行某些操作,并且在正常情况下检索数据)。我认为原始提问者对异常后仍会执行延迟查询感到惊讶。这是什么意思“正常变量“record”?我应该将其称为局部变量,比如,而不是使用@record=record.valid,我们指定record=record.vali您是否使用某种异常通知gem?如果没有