如何有效地解决NoMethodError(rails)?

时间:2015-08-26 12:42:01

标签: ruby-on-rails ruby

我是rails的新手并注意到一个非常奇怪的模式。我认为Django中的一些错误消息是含糊不清的,但是在rails中构建我的第二个应用程序我注意到我的错误超过90%的时间出现NoMethodError。

rails人员如何区分具有相同名称的所有这些错误?

NoMethodError对它的核心意味着什么?您在模板中调用的内容似乎拼写错误,或者您正在访问不存在的属性?

这个错误发生在哪里?是模板/视图中唯一可能的原因(html.erb文件)?或者控制器中的错误调用可能导致同样的错误?

此外,缓解这些问题的最佳调试器宝石是什么?至少在一段时间内,阅读完整的跟踪对初学者来说并没有太大的帮助,我想了解一个人用什么调试器而不是阅读炒作的第一手资料

谢天谢地

3 个答案:

答案 0 :(得分:1)

NoMethodError表示您正在调用对象上的方法,但该对象不提供此类方法。

这是一个非常糟糕的错误,因为它揭示了一个设计糟糕且经过测试的应用程序。它通常意味着您的代码没有按预期运行。

减少此类错误的方法是:

  • 确保在编写代码时,您正在处理可能发生的各种边缘情况,而不仅仅是正确的路径。换句话说,您需要注意验证发生了什么,并确保如果某些内容不成功(例如,用户未提供所有请求的输入),您的应用程序将优雅地处理该案例。
  • 确保编写涵盖代码库中每种方法行为的自动测试用例
  • 跟踪错误。发生错误时,编写测试以重现行为,修复代码并检查测试通过。这将降低回归的风险。

答案 1 :(得分:0)

  

rails人员如何区分所有这些错误   同名?

我们通常会查看响应(在开发模式下)以及查看日志时返回的堆栈跟踪。在开发环境中,我在控制台中运行我的服务器,我可以在其中滚动请求。

  

NoMethodError对它的核心意味着什么?看起来就像你一样   在模板中调用拼写错误,或者您正在访问属性   那不存在?

由于Ruby的动态耦合特性。当Ruby确定一个对象没有一个被调用者的名字的方法时。它在该对象中查找名称为“method_missing”的方法。如果没有定义,则调用super one,它具有引发异常的默认行为。 Rails在内部调度中充分利用了这种机制

  

这个错误发生在哪里?是唯一可能的原因   模板/视图(html.erb文件)?或者可以在控制器中进行错误调用   什么导致同样的错误?

只要你有Ruby代码,就会发生这个错误,它与rails

无关
  

此外,缓解这些问题的最佳调试器宝石是什么?读   至少在一段时间内,完整的痕迹对于初学者来说并没有太大的帮助,   我想了解一个人使用什么调试器的第一手资料   阅读炒作

一个非常宝贵的调试工具是gem'prey'。它有许多有用的可插拔工具,可以大大简化调试

答案 2 :(得分:0)

实际上这不是Rails特定的错误。我将尝试解释其核心发生的事情。

Ruby是一种通过消息传递起作用的语言。对象通过彼此发送消息进行通信。

需要将消息定义为对象上的响应方法。这可以直接在对象本身,对象的类,对象的类的父/祖先或通过包含的模块定义。

class MyObject
  def some_method
    puts "Yay!"
  end
end

> MyObject.new.some_method
Yay!

对象可以定义method_missing来处理意外消息。

class MyObject
  def method_missing(name, *args, &block)
    puts name
  end
end

> MyObject.new.some_undefined_method
some_undefined_method

如果没有method_missing处理程序,该对象将引发NoMethodError

class MyObject
end

> MyObject.new.some_undefined_method
NoMethodError: undefined method 'some_undefined_method' for #<MyObject...>

那么在Rails中这是什么样的?

$ rails generate model User name:string

制作此

# models/user.rb
class User < ActiveRecord::Base
end

其中包括以下方法(通过ActiveRecord实现)

  def name
  end

  def name=(value)
  end

执行以下操作时:

# create a new User object
> user = User.new 
#<User ... >

# call the 'name=' method on the User object
> user.name = "name" 
"name"

# call the 'name' method on the User object. Note that these are 2 different methods
> user.name
"name" 

> user.some_undefined_method
NoMethodError: undefined method 'some_undefined_method' for #<User...>

无论是在控制台,模型,控制器还是在视图中调用它,都会看到相同的结果,因为它们都运行相同的Ruby代码。

ERB视图模板略有不同,因为您输入的内容仅在<% %><%= %>之间被评估为Ruby代码。否则,它将以文本形式写入页面。