2017-01-13 11 views
0

私はメッセージクラスのメソッドを呼び出そうとすると、いつもnailの` email 'という未定義メソッド `email'を得ることができません。定義されていないメソッド `email for nil:NilClassをインデックス内にレンダリングするとき

index.html.erbメッセージ:

<div class="callout"> 
    <div class="messages-box"> 
    <% @messages.each do |message| %> 
     <% user_status = message.user_id == current_user.id ? "reciever" : "sender" %> 
     <div class="<%= user_status %> callout"> 
     <p><%= message.body %></p> 
     <p><%= message.user.email %></p> 
     </div> 
    <% end %> 
    <%= simple_form_for([@conversation, @message]) do |f| %> 
     <%= f.input :body %> 
     <%= f.hidden_field :user_id, value: current_user.id %> 
     <%= f.submit "Add Reply", class: 'button' %> 
    <% end %> 
    </div> 
</div> 

メッセージコントローラ:私はフォームを削除するか、対応するインデックス・アクションから@messageインスタンス変数を削除する場合

class MessagesController < ApplicationController 
    before_action :setup_conversation 

    def index 
    @messages = @conversation.messages 
    @message = @conversation.messages.new 
    end 

    def new 
    @message = @conversation.messages.new 
    end 

    def create 
    @message = @conversation.messages.new(message_params) 

    redirect_to conversation_messages_path(@conversation) if @message.save 
    end 

    private 

    def setup_conversation 
    @conversation = Conversation.find(params[:conversation_id]) 
    end 

    def message_params 
    params.require(:message).permit(:body, :user_id) 
    end 
end 

が正常に動作しコントローラが必要ですが、私はインデックスビューのフォームに必要です。

答えて

1

これはかなり興味深いケースです。なぜなら、あなたはActiveRecordコレクションプロキシによってビットを取得しているからです。

@messages = @conversation.messages 

はそれが持っていないどのような、しかし、次のとおりです。この行で

、あなたが実際にデータベースからすべてのレコードを持っていない ActiveRecord_Associations_CollectionProxyのサブクラスのインスタンスである、 @messagesを割り当てますすでに @conversationに割り当てられている Conversationのインスタンスを参照してください。あなたはまだこの時点で任意のSQLクエリを行っていない

@message = @conversation.messages.new 

:次の行で

は、あなたが同じ @conversationに関連付けられている Messageの新しいインスタンスを作成します。その後、我々は、クエリをトリガーする、あなたは @messageseachを呼び出し、レンダリング、入る:

@message.each do |message| 
    ... 
end 

CollectionProxyがシンプルAssociationRelationよりも洗練されているので、それはあなたのデータベースからデータを合体 - User協会で保存されたレコードを - コレクション内の新しいデータ - 非永続化されたデータ@message

結果は、このブロックの内部では、最後のmessage.userは設定されていないnilです。 Rubyはmessage.body(これはnil)をレンダリングしてnil[email protected]を比較しているので、これは前の行では爆発しません。

+0

詳細な説明ありがとうございます。私はそれがメッセージのインスタンスとメッセージのコレクションで一括して何かする気がしましたが、私は理由を理解できませんでした。あなたの説明はそれを完全に説明します。この問題を回避する方法についての推奨事項はありますか? –

+0

@NormanChan新しいレコードをアソシエーションから構築する必要がないように見えるので、会話を参照せずに '@message = Message.new'に切り替えます。あなたの 'create'アクションと' form_for'は '@ conversation'と' @ message'の両方を使います。 – coreyward

+0

ありがとう! –

関連する問題