2016-10-25 11 views
0

チュートリアルに続いて、ユーザーは私のアプリケーションでメッセージを送信できます。私は認証のためにdeviseを使用しています。基本的に、2人以上のユーザーが会話を持ち、1人以上がアカウントをキャンセルすると、残りのユーザーは会話のインデックスページにアクセスできなくなります。私はActiveRecord::RecordNotFoundConversationsController#indexに入れます。ユーザー間にメッセージがあり、ユーザーが自分のアカウントを削除した場合、もう1人のユーザーはRailsのメッセージインデックスにアクセスできなくなります。

太字のコードは、エラーが特定された場所です。これを解決する最良の方法は何でしょうか?事前に

おかげ

Indexビュー:

<% @conversations.each do |conversation| %> 
    <% if conversation.sender_id == current_user.id || conversation.recipient_id == current_user.id %> 
    <% if conversation.sender_id == current_user.id %> 
     **<% recipient = User.find(conversation.recipient_id) %>** 
    <% else %> 
     <% recipient = User.find(conversation.sender_id) %> 
    <% end %> 
    <tr> 
     <td><%= link_to (image_tag recipient.avatar.url, size: "50x50"), user_path(recipient) %></td> 
     <td><%= recipient.full_name %></td> 
     <td><%= link_to "View Message", conversation_messages_path(conversation) %></td> 
    </tr> 
    <% end %> 
<% end%> 

コントローラー:

class ConversationsController < ApplicationController 
    def index 
    @users = User.all 
    @conversations = Conversation.all 
    end 

    def create 
    if Conversation.between(params[:sender_id],params[:recipient_id]) 
    .present? 
     @conversation = Conversation.between(params[:sender_id], 
     params[:recipient_id]).first 
    else 
    @conversation = Conversation.create!(conversation_params) 
    end 
    redirect_to conversation_messages_path(@conversation) 
    end 

    private 
    def conversation_params 
    params.permit(:sender_id, :recipient_id) 
    end 
    end 

モデル:

class Conversation < ActiveRecord::Base 
    belongs_to :sender, :foreign_key => :sender_id, class_name: 'User' 
    belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'User' 

    has_many :messages, dependent: :destroy 

    validates_uniqueness_of :sender_id, :scope => :recipient_id 

    scope :between, -> (sender_id,recipient_id) do 
    where("(conversations.sender_id = ? AND conversations.recipient_id =?) OR (conversations.sender_id = ? AND conversations.recipient_id =?)", sender_id,recipient_id, recipient_id, sender_id) 
    end 
end 
+0

<%= link_to (image_tag recipient.avatar.url, size: "50x50"), user_path(recipient) %> 

を変更。インデックスビュー自体を投稿しても、エラーの原因を特定するのに役立つわけではありません。 – angkiki

答えて

0

ええ、それは問題です。存在しないユーザーレコードに対して多くの呼び出しが行われています。

recipient = get_the_user(conversation.recipient_id) 
recipient = get_the_user(conversation.sender_id) 

...と

私はあなたが交換することをお勧めしたい...

recipient = User.find(conversation.recipient_id) 

recipient = User.find(conversation.sender_id) 

あなたはヘルパーメソッドが必要になります...あなたあなたの中に入れることができますApplicationController

class ApplicationController 

    helper_method :get_the_user 

    DummyUser= Struct.new(:full_name) 

    def get_the_user(id) 
    user = User.find_by(id: id) 
    return user if user 
    user = DummyUser.new('deleted user') 
    end 

そして、あなたは存在しないユーザーにリンクすることができないとして、あなたは同様にあなたのコントローラ&モデルを投稿する必要があり

<%= recipient.class == User ? link_to (image_tag recipient.avatar.url, size: "50x50"), user_path(recipient) : 'no link available' %> 
+0

Btw @モーリスこれは私の答えの解決(1)です。私はそれが間違っているとは言わない、それはあなたが欲しいものと必要なものに応じて、異なったことをする完璧な例です。この場合:ユーザーがあなたのサービスに不満を持ち、アカウントをキャンセルした場合、彼のメッセージは削除されません。 – everyman

0

はあなたが望むものに依存します。

  1. ユーザーは「削除済み」とマークする必要がありますが、メッセージは読み取り可能です。
  2. ユーザーの1人が削除されると、メッセージも破棄されます。
  3. メッセージは、ユーザーのための読みではありませんが、管理者...(私は考えることができ、最悪のアイデア)

芋(2)移動するための方法です。 Userモデルのようなものを持っている必要があります。

has_many :conversations, dependent: :destroy 

そして芋あなたの質問は、あなたが考えるよりも、より基本的です。ソフトウェア開発は、しばしばコードを作成するよりも意思決定を行うことが多い。

+0

私は2番のソリューションを試しましたが、それでもうまくいきません:-( – Maurice

+0

テストデータをリセットしましたか?(もちろん、削除されたオブジェクトに関連する会話がまだ存在する場合は、これは機能しません) – everyman

+0

これは私も同様に考えて試しましたが、うまくいかなかったのです。 @steveturczynによって提供された解決策はちょうど少しそれを微調整しなければならなかった – Maurice

関連する問題