2

次のようなエラーメッセージが常に表示されます。

undefined method 'firm_size' for nil:NilClass

コレクションを繰り返し処理しているときに、いくつかの nil ケースが発生します。

ifnil ケースを処理するには、通常、自分のビューに移動して、この特定の属性の周りにステートメントを追加する必要があります。

これは非常に非 DRY なアプローチのようです。

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.scorewhen 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スコアが割り当てられていない Client レコード用です。

4

2 に答える 2

0

特定のケースでは、がヘルパーであると仮定best_in_placeすると、ヘルパーで nil を処理できます。clientではなく、を渡すだけclient.scoreです。

ポイントは、どこかに if ステートメントがあることです。ベストな位置に置くだけ。

于 2012-10-11T00:05:27.573 に答える
0

コードが nil であってはならないものに対して一貫して nil を返す場合は、関数の呼び出し方法を再考するのが最善かもしれません。ただし、(または多数の)カスタム nil クラスがあると便利な場合がよくあります。あなたが持っている関数をキャッチするために拡張機能を書くことができNilCLassますが、異なる状況で同じ関数名を取得する場合、これは問題になる可能性があります. 特定の属性が nil の場合、ヘルパー メソッドが指すすべてのクラスにシングルトンを作成する可能性もあります。

于 2012-10-11T00:07:07.573 に答える