如何在整个应用程序中优雅地处理集合中的nil个案?

时间:2012-10-10 23:40:43

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

我总是会收到如下错误消息:

undefined method 'firm_size' for nil:NilClass

当迭代一个集合并出现一些零的情况时。

我通常必须进入我的视图并在此特定属性周围添加if语句来处理nil个案。

这似乎是一种非常干燥的方法。

在Rails中处理这些类型的案例是否有更优雅的方法?不仅是集合中的nil个对象,还有可能具有nil属性的对象 - 这实际上就是这里发生的事情。

感谢。

修改1

有关此特定错误实例的更多上下文:

这是我的Scores#index视图 -

<% @clients.each do |client| %>
  <tr>
    <td><%= "First Client" %></td>
  </tr>
  <tr>
    <td>Firm Size</td>
    <td><%= best_in_place client.score, :firm_size, :type => :input, :nil => "Add Score for Firm Size" %></td>

这是我的scores_controller.rb相关部分:

class ScoresController < ApplicationController
    before_filter :load_clients

  def index
    @weight = current_user.weight
    @scores = current_user.scores

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @scores }
    end
  end

    private 

    def load_clients
        @clients = current_user.clients     
    end         

end

这是服务器日志:

Started GET "/scores" for 127.0.0.1 at 2012-10-10 18:38:05 -0500
Processing by ScoresController#index as HTML
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Weight Load (0.2ms)  SELECT "weights".* FROM "weights" WHERE "weights"."user_id" = 1 LIMIT 1
  Client Load (0.3ms)  SELECT "clients".* FROM "clients" WHERE "clients"."user_id" = 1
  Score Load (10.9ms)  SELECT "scores".* FROM "scores" WHERE "scores"."client_id" = 1 LIMIT 1
  Score Load (0.3ms)  SELECT "scores".* FROM "scores" WHERE "scores"."client_id" = 2 LIMIT 1
  Rendered scores/index.html.erb within layouts/application (276.6ms)
Completed 500 Internal Server Error in 283ms

这是有问题的记录(例如client.score时的client.id = 2

1.9.3p194 :089 > d = Client.find(2)
  Client Load (0.2ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1  [["id", 2]]
 => #<Client id: 2, name: "Jack Daniels", email: "jack@abc.com", phone: 1234567890, firm_id: 2, created_at: "2012-09-05 19:26:07", updated_at: "2012-10-07 02:44:51", user_id: 1, last_contact: "2012-02-10", vote: false, vote_for_user: false, next_vote: "2012-07-12", weighted_score: nil> 
1.9.3p194 :090 > d.score
  Score Load (0.4ms)  SELECT "scores".* FROM "scores" WHERE "scores"."client_id" = 2 LIMIT 1
 => nil 

正如我之前所说,只要遇到nil记录(或属性),就会引发此错误。在这种特殊情况下,nil记录用于已分配无分数的2nd客户端记录。

2 个答案:

答案 0 :(得分:0)

在您的特定情况下,假设best_in_place是帮助程序,您可以在帮助程序中处理nil。只需传递client,而不是client.score

关键是某处你会有一个if语句。把它放在最佳位置。

答案 1 :(得分:0)

如果你的代码对于不应该为nil的东西一直返回nil,那么也许最好重新考虑函数的调用方式。虽然拥有(或众多)自定义nil类通常很好。您可以在NilCLass上编写扩展来捕获您拥有的函数,但如果您获得的函数名称在不同情况下相同,则可能会出现问题。如果特定属性为nil

,您还可以在辅助方法指向的所有类中创建单例