簡體   English   中英

NoMethodError - nil:NilClass 的未定義方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM