2016-05-05 4 views
1

私は、このガイドに沿って、http://www.tobyh.com/thoughts/4をソーシャルアプリ用の2ウェイ友好システムにしました。これを1週間以上にわたって作業した後で、このガイドに従うことは私がこの作業を行うのに最も近いところですが、最終製品には深刻な問題がたくさんあります。それの最初の3分の1だけが動作し、友人のリクエストを送信します。友人の要求を受け入れることも拒否することもできません。NoMethodError - 定義されていないnilメソッド:NilClass

routes.rbを

resources :friendships, only: [:create, :update, :destroy] 

friendship.rb

class Friendship < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :friend, :class_name => 'User' 
end 

user.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 :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.) 

:ここでは、これを説明する開始するに

はの関連する部分ですfriendships_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 
     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人の友人のリクエストを送信しようとすると、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フレンドリクエストを送信した後、デフォルトで「受け入れ」が「false」に設定されます。これは、「Facebookスタイル」のフレンドリクエストシステム - ウェイ "ツイッタースタイル"。

この問題の作業に多大な時間を費やしたため、私は多種多様な問題やエラーメッセージを経験しました。そのほとんどはもはや問題ではありません。友人のリクエストを受け取った時点から、プロフィールページで[拒否]をクリックすると、現在存在する問題が表示されます。

まず、すべてが問題なく表示されます。あなたのプロフィールページがリフレッシュされ、「友達リクエストが拒否されました」 friendships_controller.rbのメッセージが意図したとおりに表示されます。ただし、フレンドリクエストタブをクリックすると、あなたが拒否したフレンドリクエストがまだそこにあることがわかります。上の写真と左のフラッシュメッセージがない場合の写真はhttp://i.imgur.com/Dg1uTXf.pngです。友人の要求を2回以上辞退しようとすると、この問題のタイトルにエラーメッセージが表示されます。 http://i.imgur.com/XBhNtkF.png

友だちのリクエストが既にになっているので、それは失敗しているようです。右はでしょうか?限り、私は言うことができる:いいえ!私はそれがこの写真の内容のために真実ではないと信じています:http://i.imgur.com/UOIYnHP.pngデータベースの新しいコピーをダウンロードした後、それはさらに友人の数が以前よりも多いと主張しています! 2の代わりに3人の友人のリクエストがあり、そのうちの1人にfriend_idが添付されていません。これはまた、フレンドリクエストが[フレンドリクエスト]タブの下に存続する理由を説明します。

さらに、ログアウトしてフレンドリクエスト送信者のアカウントにログインし、2番目のフレンドリクエストを受信者に送信しようとすると、次のエラーメッセージが表示されます。http://i.imgur.com/q0WsVCB.png SQLite3 :: ConstraintException in FriendshipController#create UNIQUE制約に失敗しました:friendships.user_id、friendships.friend_id 友だちにインデックスを追加した結果、ユーザーが同じ人から2人以上の友だちリクエストを受け取ることができなくなりました。つまり、Declineをクリックしても友人のリクエストが本当に削除されるわけではなく、友人のリクエストがデータベースの3番目の友だちエントリを作成するという意図しない効果を持つ「friend_id」部分のみが削除されるということです。

Whew!それはかなりの情報でしたが、それは「拒否」リンクのみをカバーしています。今すぐ "Accept"リンクをクリックしてください!

ログインして新しい友達リクエストを受け取り、それを受け入れると、2回連続して友だちリクエストを拒否しようとしたときと同じエラーメッセージが表示されますが、更新メソッドの代わりに、destroyメソッド:http://i.imgur.com/IHptXDu.png NoMethodError in FriendshipsController#update 未定義のメソッドupdate for nil:NilClass これはなぜわかりません。

この問題の写真を書いていて、私はこの繰り返しの行:show.html.erbの下に "friendship_path(id:request.id)"と気付き、このデータベースの画像と比較して考えました:http://i.imgur.com/UOIYnHP.png友だちリクエストを削除するために拒否をクリックすると、その友だちリクエストをリクエストしたユーザーのIDを削除するだけです(その写真のfriend_idではなくuser_idです)。問題は、show.html.erbの下にあるDecline and Acceptリンクの形式である可能性があります。

私が書くことができるすべてについて書いたと思います!この質問がどれくらいの間、残念ですか、それを読む時間をとっていただきありがとうございます。私は本当に心の底からそれを感謝します!

+1

破壊アクションにあなたのパラメータがどのように見えますか? –

+0

"authenticity_token" => "ABCD123etc。=="、 "id" => "1"} – Display

+1

このエラーの画像:http://i.imgur.com/ XBhNtkF.png params [:friend_id]を探していますが、上のコードでparams [:id]を探していると表示されています。実際に参照しているコードはどれですか? –

答えて

1

私は1週間以上前にこれを追加するつもりでしたが、ここでは私のために働いていました。

friendship.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 

user.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 

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

他はすべて同じです。

関連する問題