Неопределенный метод «уничтожить» при попытке разрушить/отклонить дружеские отношения

Я настроил модель отношений с ссылками на самих себя, чтобы пользователи могли дружить друг с другом. Я могу без проблем создать запрос на добавление в друзья (две записи в моей БД, одну для дружбы и одну для обратной дружбы).

Однако у меня возникли проблемы с отклонением запроса на добавление в друзья. Я продолжаю получать эту ошибку, когда нажимаю «Отклонить», что приводит меня к действию «уничтожить»:

NoMethodError in FriendshipsController#destroy
undefined method `destroy' for nil:NilClass

Одна из записей базы данных, ожидающая дружбы, уничтожается, хотя я получаю указанную выше ошибку, и если я закомментирую @friendship2 = @user.friendships.find_by_friend_id(params[:id]).destroy, другая запись тоже будет уничтожена. Таким образом, похоже, что обе строки работают по отдельности, но возвращают указанную выше ошибку.

РЕШЕНИЕ. Похоже, что два моих оператора уничтожения ссылались на одну и ту же запись. Я закомментировал неправильный код в своем контроллере и добавил те, которые мне подходят.

Вот мой контроллер Дружбы:

class FriendshipsController < ApplicationController
  before_filter :authenticate, :only => [:update, :create, :destroy]

def create
  @user = User.find(current_user)
  @friend = User.find(params[:friend_id])
  params[:friendship1] = {:user_id => @user.id, :friend_id => @friend.id, :status => 'requested'}
  params[:friendship2] = {:user_id => @friend.id, :friend_id => @user.id, :status => 'pending'}
  @friendship1 = Friendship.create(params[:friendship1])
  @friendship2 = Friendship.create(params[:friendship2])
  redirect_to @friend
 end  
end

  def destroy
    @user = User.find(params[:user_id])
    @friend = User.find(params[:id])
    #@friendship2 = @user.friendships.find_by_friend_id(params[:id]).destroy
    #@friendship1 = @friend.friendships.find_by_id(params[:user_id]).destroy  
    @friendship1 = @user.friendships.find_by_friend_id(@friend.id).destroy #removes the requested friendship
    @friendship2 = @friend.friendships.find_by_friend_id(@user.id).destroy #removes the pending friendship

    flash[:success] = "Removed."
    redirect_to @user   
  end 
end

Вот моя модель пользователя:

class User < ActiveRecord::Base
  has_many :friendships, :dependent => :destroy

  has_many :friends, 
     :through => :friendships, 
     :conditions => "status = 'accepted'", 
     :source => :friend 

  has_many :pending_friends, 
     :through => :friendships, 
     :conditions => "status = 'pending'", 
     :foreign_key => "user_id", 
     :source => :friend

  has_many :requested_friends, 
     :through => :friendships,
     :source => :friend, 
     :conditions => "status = 'requested'"    
end

Вот мое мнение (users/show.html.erb):

<% if signed_in? && @user == current_user %>
  <% unless current_user.pending_friends.empty? %>
    <h2>Pending</h2>
    <% current_user.pending_friends.each do |pending| %>
       <%= pending.name %>
       <%= link_to '[Accept]', friendship_path(:user_id => current_user, :id => pending), :method => :put, :confirm => "Accept?" %>
       <%= link_to '[Decline]', friendship_path(:user_id => current_user, :id => pending), :method => :delete, :confirm => "Decline?" %>
    <% end %>
  <% end %>
<% end %>

У меня есть два вопроса.

  1. Я видел из некоторых руководств/обсуждений о использование inverse_friendships, но действительно ли это необходимо? До сих пор я не видел в этом необходимости, но опять же, я добрался только до кодирования своего действия создания и уничтожения.

  2. Что случилось с ошибкой undefined method 'destroy'?

Спасибо, что преодолели эту стену текста! :D


person Huy    schedule 30.03.2012    source источник


Ответы (2)


Что касается первого, это зависит от вас и вашей системы. Создание разных переменных для хранения каждого типа дружбы может быть немного сложным, но это дает вам полную информацию, больший контроль и отсутствие дублирования данных в базе данных.

Что касается второго, вы должны проверить, возвращает ли ваш запрос результат. С момента вашего исключения:

неопределенный метод `уничтожить' для nil:NilClass

Говорит, что в NilClass нет метода "уничтожить" (не дружба). Просто проверьте параметр :id и вернет ли find_by_friend_id что-нибудь вообще.

person Dmitry Reznik    schedule 30.03.2012
comment
Спасибо за разъяснение обоих вопросов. У меня все еще возникают проблемы с поиском ошибки, и я также включил свое представление. Думаю проблема в строке @friendship1 = @friend.friendships.find_by_id(params[:user_id]).destroy. Простите мою неопытность (все еще новичок в Rails). Я продолжу изучать это. - person Huy; 30.03.2012
comment
Спасибо за помощь. Это в конечном итоге привело меня к открытию ответа. - person Huy; 30.03.2012

Поставьте галочку перед уничтожением.

friendship = @friend.friendships.find_by_id(params[:user_id])
@friendship1 = friendship.destroy if !friendship.nil?

А также можно превратить эту историю в модель с помощью обратных вызовов. .

person Vik    schedule 30.03.2012
comment
Это помогло мне приблизиться к решению. Несмотря на то, что это удалило сообщение об ошибке, оно по-прежнему не удаляет файл request_friendship. Я смог выяснить, что мои два уничтожения ссылаются на одну и ту же запись. Теперь мне просто нужно выяснить, как передать friend_id как user_id... - person Huy; 30.03.2012
comment
Спасибо за помощь, Вик. Я смог понять это. Поставил Дмитрию галочку, но проголосовал и за вас. - person Huy; 30.03.2012