[英]NoMethodError - undefined method for nil:NilClass
我遵循本指南: http : //www.tobyh.com/thoughts/4為社交應用程序制作了一個雙向友誼系統。 在連續研究了一個多星期之后,遵循該指南是迄今為止我最接近完成這項工作的方法,但最終產品有很多嚴重的問題。 只有前三分之一有效 - 發送好友請求。 接受或拒絕好友請求都不起作用。
為了開始解釋這一點,以下是以下相關部分:
路由文件
resources :friendships, only: [:create, :update, :destroy]
友誼.rb
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => 'User'
end
用戶名
class User < ActiveRecord::Base
has_many :friendships, dependent: :destroy
has_many :received_friendships, class_name: "Friendship", foreign_key: "friend_id", dependent: :destroy
has_many :active_friends, -> { where(friendships: { accepted: true}) }, through: :friendships, source: :friend
has_many :received_friends, -> { where(friendships: { accepted: true}) }, through: :received_friendships, source: :user
has_many :pending_friends, -> { where(friendships: { accepted: false}) }, through: :friendships, source: :friend
has_many :requested_friendships, -> { where(friendships: { accepted: false}) }, through: :received_friendships, source: :user
attr_accessor :remember_token, :activation_token, :reset_token (I've spent more than 20 hours on slogging through google and
stackoverflow alone, and I have a fuzzy memory of someone saying that attr_accessor might be relevant to this problem, but
I only saw it mentioned in a single question out of more than 20, so I'm not sure if it really is relevant.)
友誼控制器.rb
class FriendshipsController < ApplicationController
def create
@friendship = current_user.friendships.build(friend_id: params[:friend_id])
if @friendship.save
flash[:notice] = "Friend request sent!"
redirect_to :back
else
flash[:error] = "Unable to send friend request."
redirect_to :back
end
end
def update
@friendship = Friendship.find_by(id: params[:id])
@friendship.update(:accepted, true)
if @friendship.save
redirect_to root_url, notice: "Friend request accepted."
else
redirect_to root_url, notice: "Unable to accept friend request."
end
end
def destroy
@friendship = Friendship.find_by(id: params[:id])
@friendship.destroy
flash[:notice] = "Friend request declined."
redirect_to :back
end
end
_user.html.erb,這是顯示每個用戶的索引頁,帶有分頁。 這是唯一相關的部分:
<% if logged_in? && !current_user?(user) %>
<%= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post %>
<% end %>
和 show.html.erb,它顯示用戶的個人資料頁面。 在此頁面和用戶索引頁面上,只要您以該用戶以外的其他人身份登錄,您就可以看到並使用“添加朋友”按鈕。 此外,由於索引,如果您嘗試向某人發送 2 個好友請求,第二個好友請求將失敗。
<% if logged_in? && !current_user?(@user) %>
<%= link_to "Add Friend", friendships_path(:friend_id => @user), :method => :post %>
<% end %>
...
<ul class="nav nav-tabs">
...
<% if logged_in? && current_user?(@user) %>
<li><a data-toggle="tab" href="#friendreqs">Friend Requests</a></li>
<% end %>
</ul>
...
<div id="friendreqs" class="tab-pane fade">
<h3>Friend Requests</h3>
<ul>
<% if current_user?(@user) %>
<% current_user.requested_friendships.each do |request| %>
<li>
<%= request.name %>
<%= link_to "Accept", friendship_path(id: request.id), method: "put" %>
<%= link_to "Decline", friendship_path(id: request.id), method: :delete %>
</li>
<% end %>
<% end %>
</ul>
</div>
現在,無論您是使用用戶個人資料頁面上的“添加好友”鏈接還是用戶索引中他們姓名旁邊的“添加好友”鏈接,發送好友請求似乎都有效。 這是登錄用戶 #3、從他們的個人資料頁面將用戶 #2 添加為朋友並通過索引頁面將用戶 #1 添加為朋友后的控制台圖片: http : //i.imgur.com/MbsBKot。 png還有一張 SQL 數據庫瀏覽器的圖片,似乎也確認了初始好友請求發送成功: http : //i.imgur.com/cX45vm8.png “accepted”在發送好友后默認設置為 false請求,因為我希望它是一個“facebook 風格”的好友請求系統,而不是一個單向的“twitter 風格”。
由於在這個問題上花費了大量時間,我遇到了各種各樣的問題和錯誤消息,其中大部分不再重要。 從接收好友請求開始,以下是您在個人資料頁面上單擊“拒絕”后當前存在的問題。
起初,一切似乎都很好。 您的個人資料頁面會刷新並顯示“好友請求被拒絕”。 Friendships_controller.rb 中的消息按預期顯示。 但是,當您單擊“好友請求”選項卡時,您會看到您拒絕的好友請求仍然存在。 這是一張圖片,沒有上方和左側的 Flash 消息: http : //i.imgur.com/Dg1uTXf.png如果您嘗試第二次(或多次)拒絕好友請求,您會收到錯誤消息在這個問題的標題中。 這也是一張照片: http : //i.imgur.com/XBhNtkF.png
這似乎表明它失敗了,因為好友請求已被成功拒絕,對嗎? 據我所知:不! 我相信這是因為這幅畫的內容不正確的: http://i.imgur.com/UOIYnHP.png下載數據庫的新副本后,聲稱還有比有以前更大數量的友誼! 3 個好友請求而不是 2 個,其中一個沒有附加friend_id。 這也可以解釋為什么好友請求會在“好友請求”選項卡下持續存在。
最重要的是,如果您注銷,登錄好友請求發送者的帳戶,並嘗試向接收者發送第二個好友請求,您將收到此錯誤消息: http : //i.imgur.com/ q0WsVCB.png SQLite3::ConstraintException in FriendshipsController#create UNIQUE 約束失敗:friendships.user_id, friends.friend_id我很確定這是向友誼添加索引的結果,這會阻止用戶收到來自同一個人的 2 個或更多好友請求. 這再次意味着單擊拒絕並不會真正刪除好友請求,只會刪除其中的“friend_id”部分,這會產生在數據庫中創建第三個好友條目的意外效果。
哇! 這是相當多的信息,但僅涵蓋“拒絕”鏈接。 現在是“接受”鏈接!
如果您登錄,看到一個新的好友請求,並嘗試接受它,您將收到與嘗試連續 2 次拒絕好友請求時相同的錯誤消息,但此消息引用的是更新方法銷毀方法: http ://i.imgur.com/IHptXDu.png NoMethodError in FriendshipsController#update undefined method `update' for nil:NilClass 我不知道為什么會這樣。
在寫這個問題並拍照的時候,注意到show.html.erb下有這么一行重復:“friendship_path(id: request.id)”,對比這個數據庫圖片想了一下: http://i .imgur.com/UOIYnHP.png如果點擊拒絕刪除好友請求時,它只是刪除了請求好友請求的用戶的 ID(在該圖中,是 user_id,而不是friend_id)怎么辦? 問題可能是show.html.erb下的拒絕和接受鏈接的格式,其他一切都很好..?
我想我已經寫了幾乎所有我能寫的東西! 我很抱歉這個問題問了多久,感謝您花時間閱讀它; 我真的從心底里感激它!
我打算在一周前添加這個,但這是最終對我有用的東西。
友誼.rb:
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => 'User'
validates :user_id, presence: true
validates :friend_id, presence: true
end
用戶.rb:
class User < ActiveRecord::Base
has_many :friendships, dependent: :destroy
has_many :received_friendships, class_name: "Friendship", foreign_key: "friend_id", dependent: :destroy
has_many :passive_friends, -> { where(friendships: { accepted: true}) }, through: :received_friendships, source: :user
has_many :active_friends, -> { where(friendships: { accepted: true}) }, :through => :friendships, :source => :friend
has_many :requested_friendships, -> { where(friendships: { accepted: false}) }, through: :received_friendships, source: :user
has_many :pending_friends, -> { where(friendships: { accepted: false}) }, :through => :friendships, :source => :friend
friends_controller.rb:
class FriendshipsController < ApplicationController
def create
@friendship = current_user.friendships.build(friend_id: params[:friend_id])
if @friendship.save
flash[:notice] = "Friend request sent!"
redirect_to :back
else
errors.add(:friendships, "Unable to send friend request.")
redirect_to :back
end
end
def update
@friendship = Friendship.where(friend_id: [current_user, params[:id]], user_id: [current_user, params[:id]]).first
@friendship.update(accepted: true)
if @friendship.save
redirect_to :back, notice: "Friend request accepted."
else
redirect_to :back, notice: "Unable to accept friend request."
end
end
def destroy
@friendship = Friendship.where(friend_id: [current_user, params[:id]]).where(user_id: [current_user, params[:id]]).last
@friendship.destroy
flash[:notice] = "Friend request declined."
redirect_to :back
end
end
show.html.erb:
<% current_user.requested_friendships.each do |request| %>
<% if request.id == @user.id %>
<%= link_to "Accept Friend Request", friendship_path(id: request.id), method: "put" %><br>
<%= link_to "Decline Friend Request", friendship_path(id: request.id), method: :delete %>
<% end %>
<% end %>
<% if logged_in? && !current_user?(@user) && Friendship.where(friend_id: [current_user, params[:id]], user_id: [current_user, params[:id]]).first == nil %>
<%= link_to "Add Friend", friendships_path(:friend_id => @user), :method => :post %>
<% end %>
其他一切都是一樣的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.