2013-07-27 37 views
0

我似乎無法讓Amistad友誼正常工作。我收到以下錯誤:如何創建好友?

ActiveRecord::RecordNotFound in FriendshipsController#update 
Couldn't find Friendship with id=29 

我也使用devise和cancan。我遵循維基頁面上的創業板設置,並按this related post中所述創建了我的控制器。

class FriendshipsController < ApplicationController 

    before_filter :authenticate_user! 

    def index 
    @friends = current_user.friends 
    @pending_invited_by = current_user.pending_invited_by 
    @pending_invited = current_user.pending_invited 
    end 

    def create 
    @friend = User.find(params[:user_id]) 
    @friendship_created = current_user.invite(@friend) 
    if @friendship_created 
     redirect_to users_path, :notice => "Your friend request is pending" 
    end 
    end 

    def update 
    @friend = User.find(params[:user_id]) 
    @friends = current_user.friends 
    @pending_invited_by = current_user.pending_invited_by 
    redirect_to users_path, :notice => "You are now friends!" 
    end 

    def destroy 
    @friend = User.find(params[:user_id]) 
    @friendship = current_user.send(:find_any_friendship_with, @friend) 
    if @friendship 
     @friendship.delete 
     @removed = true 
     redirect_to users_path, :notice => "You are no longer friends!" 
    end 
    end 

    def createblock 
    @friend = User.find(params[:user_id]) 
    current_user.block @friend 

    redirect_to users_path, :notice => "You have blocked #{@friend.first_name}" 
    end 

end 

我通過以下方式循環檢查用戶的當前狀態並提供適當的操作。

<% if current_user.friend_with? user %> 
    <%= link_to "Unfriend", friend_path(user), :method => "delete", :class => 'btn btn-mini' %> 
<% elsif current_user.invited? user %> 
    <span class="btn btn-mini disabled">Pending</span> 
<% elsif user.invited? current_user %> 
    <%= link_to "Accept", friend_path(user), :method => "put", :class => 'request-approve btn btn-mini' %> 
    <%= link_to "Decline", friend_path(user), :method => "delete", :class => 'request-decline btn btn-mini' %> 
<% else %> 
    <%= link_to "Add friend", friends_path(:user_id => user), :method => "post", :class => 'btn btn-mini' %> 
<% end %> 

想通了,看看有什麼友誼表看起來像在我的架構將是有益的:

create_table "friendships", :force => true do |t| 
    t.integer "friendable_id" 
    t.integer "friend_id" 
    t.integer "blocker_id" 
    t.boolean "pending",  :default => true 
    end 

    add_index "friendships", ["friendable_id", "friend_id"], :name => "index_friendships_on_friendable_id_and_friend_id", :unique => true 

我理解的錯誤只是想不通這應如何改變。我認爲我的問題是,我傳遞了一個朋友ID,它期待着一個友誼ID。這個解決方案唯一的問題是,我可以找到的每個示例或帖子都建議傳遞user_id,就像上面這個帖子中回答者聲明gem開發者提供了他所回答的代碼一樣。

我想吃什麼,我需要在我的更新方法就是更換:

@friend = User.find(params[:id]) 

有了這個:

@friendship = Friendship.find_by_friend_id(params[:id]) 

編輯 我能成功申請的朋友,我還是無法接受或拒絕朋友。我列出了一個用戶列表,點擊「添加朋友」鏈接可以正確創建友誼數據庫中的記錄。如果我以最近請求的用戶身份登錄,並嘗試接受請求,那麼我會收到上述錯誤。如果我試圖拒絕請求,也會發生這種情況。

您要求看到的amistad寶石的朋友方法,這裏是the code for that method。至於我的Ruby日誌,顯示錯誤的部分非常長,所以我將它包含在this gist中。

+0

你可以顯示'current_user.friends'的代碼,它在那裏失敗吧?我的意思是,在日誌中,ruby抱怨哪一行? – juanpastas

+0

@juanpastas我已更新以證明您的問題的答案 – Thomas

+0

您的'development.log'說'ActiveRecord :: RecordNotFound(無法找到id = 32的友誼)'在您問題'update'正在執行'User.find'你能解釋一下嗎? – juanpastas

回答

1

查找問題是因爲您傳遞的ID不一致。在其中3個鏈接中,您直接傳遞User對象,該對象應該自動將該標識存儲在params[:id]中,您可以在該行爲中使用該標識作爲User.find(params[:id])。但在你的行動中,你從params[:user_id]中提取它,這是空的。不知道如何在錯誤消息(或32或其他)中獲得29的ID,但是...

如果你改變自己的行爲,以期望params[:id]和切換「加爲好友」路徑鏈接在User對象把別人已經成這個樣子,你應該通過正確的數據在正確的參數,並且查找應該理順自己。

當然,正如Wonky Business指出的那樣,您實際上並沒有在您的更新方法中調用approve,所以沒有任何東西可以實際鏈接,但至少您應該找到所有模型對象。

順便說一句,從您的路徑看來,您將friendship命名路線重新映射到friend。這是混淆的問題,因爲沒有一個RESTful路線實際上在做他們的名詞/動詞組合暗示的內容:如果您用POST調用friends_path(user),當完成時應該有一個新的Friend對象,但是此控制器正在創建並銷燬Friendship對象並僅保留Friend對象。

如果您刪除該別名並切換到friendship_path等等,那麼REST實際上會做它所說的:管理friendship對象。

希望有幫助!

2

鑑於我目前的名譽,我只能發佈一個答案,而不是你的問題評論,但據我從您發佈的控制器來源看,你是不是您的更新動作叫current_user.approve @friend

我最近在一個項目中使用了這個gem,但沒有遇到任何問題。控制器的動作如下所示:

def update 
    @friend = User.find_by_id(params[:id]) 
    if current_user.approve @friend 
    redirect_to friendships_path, notice: t('.confirmation_successful') 
    else 
    redirect_to friendships_path, alert: t('.confirmation_unsuccessful') 
    end 
end 

def destroy 
    @friend = User.find_by_id(params[:id]) 
    if current_user.remove_friendship @friend 
    redirect_to friendships_path, notice: t('.deletion_successful') 
    else 
    redirect_to friendships_path, alert: t('.deletion_unsuccessful') 
    end 
end 

我希望這會有所幫助。