异常处理:“未定义的方法`____'为nil:NilClass”

时间:2012-11-06 22:43:35

标签: ruby-on-rails ruby exception-handling

我的Web应用程序失败的最常见原因之一是因为用户有时缺少视图所期望的特定属性。例如,我的应用程序中的大多数用户在我们的系统中都有教育(学校,学位等)条目,但有些用户没有。假设我的观点看起来像这样:

<% @educations.each do |education| %>
  <%= education.school %>
  <%= education.degree %>
<% end %>

我想避免“口袋妖怪”异常处理,并且觉得在用户没有教育条目的情况下,必须有一个更好的方法来处理nil:NilClass的“未定义方法`度”在我们的数据库中这似乎是一个丑陋/乏味的修复:

<% @educations.each do |education| %>
  <% if education.school %>
    <%= education.school %>
  <% end %>
  <% if education.degree %>
   <%= education.degree %>
  <% end %>
<% end %>

任何输入都表示赞赏。谢谢!

2 个答案:

答案 0 :(得分:0)

只要你知道你正在处理的第一个对象不会是零,最简单的方法就是这样做:

- @educations.each do |education|
  = education.try :school
  = education.try :degree

#try方法非常方便。你也可以在你认为可能没有的任何事情上致电.to_s,即:

- @educations.each do |education|
  = education.school.to_s
  = education.degree.to_s

这会将nils转换为空字符串。这在IMO视图中没那么有用,但是如果你有一个期望是一个字符串并且可能是空的输入,那么很多时候会派上用场。就是这样的方法:

def put_in_parenthesis(string)
  "(" + string.to_s + ")"
end

答案 1 :(得分:0)

你有几个选择。

最容易实现的是try method。它的用法如下:

<%= education.try( :degree ) %>

问题是try()被视为a bit of an anti-pattern。如参考所示,您可以通过以下方式实现类似功能:

<%= education && education.degree %>

在我看来,这在理智上并没有太大的不同。一种更为干净利落的流行方式是Null Object pattern,它基本上是一个具有定义中性(“空”)行为的对象。