2016-10-25 16 views
0

我遵循教程,允許用戶在我的應用上發送其他消息。我正在使用設計進行身份驗證。基本上,如果兩個或兩個以上用戶之間有對話,並且一個或多個用戶取消了他們的帳戶,則剩下的用戶將無法再訪問索引頁進行對話。我在ConversationsController#index得到ActiveRecord::RecordNotFound如果用戶之間有消息並且用戶刪除了他的帳戶,另一個用戶將無法再訪問Rails中的消息索引。

粗體代碼是錯誤被識別的地方。解決這個問題的最好方法是什麼?

在此先感謝

索引視圖:

<% @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

你應該張貼您的控制器型號爲好。發佈索引視圖本身並不能幫助人們發現錯誤的可能性。 – angkiki

回答

0

是的,這是一個問題,你有很多在不存在的用戶記錄上進行的調用。

我建議你更換...

recipient = User.find(conversation.recipient_id) 

recipient = User.find(conversation.sender_id) 

與...

recipient = get_the_user(conversation.recipient_id) 
recipient = get_the_user(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 

正如你不能鏈接到不存在的用戶,更改

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

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

順便說一句@Maurice這是解決方案(1)在我的答案。我不認爲這是錯誤的,它是以不同方式做事的完美例子 - 取決於你想要什麼和需要什麼。在這種情況下:如果用戶對您的服務不滿意並且取消了他的賬戶,他的消息不會被刪除。 – everyman

0

取決於你想要什麼:

  1. 用戶應該被標記爲「已刪除」,但消息是可讀的。
  2. 如果其中一個用戶被刪除,消息也將被銷燬。
  3. 信息無法讀取了用戶,管理員...(最壞的想法我能想到的)

伊莫(2)是要走的路。 User型號應該是這樣:

has_many :conversations, dependent: :destroy 

和國際海事組織你的問題比你想象的更根本的。軟件開發通常比編寫代碼更關注決策。

+0

我試過2號解決方案,但這也不起作用:-( – Maurice

+0

您是否重置了您的測試數據?(當然,如果與刪除的對象相關的對話仍然存在,那麼這將不起作用) – everyman

+0

這就是我所想的並嘗試過,但沒有奏效。由@steveturczyn提供的解決方案的工作,只是不得不調整一下 – Maurice

相關問題