2012-03-20 1 views
1

У меня есть традиционная дружба модель:Rails 3 модель дружбы: как игнорировать запрос друга?

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

has_many :friendships, :dependent => :destroy 
    has_many :friends, :through => :friendships, :dependent => :destroy 
    has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id", :dependent => :destroy 
    has_many :inverse_friends, :through => :inverse_friendships, :source => :user, :dependent => :destroy 

Я хотел бы определить статус «друга», только если запрос друг был отправлен и принят другим пользователем , Все работает отлично, за исключением того, что мне не удалось обработать часть «игнорировать друга».

То, что я пытаюсь сделать, это: на странице профиля пользователя есть список запросов от другого пользователя, ожидающего утверждения. Затем пользователь может принять запрос друга (тогда он станет другом) или отклонить его (тогда отношения дружбы будут уничтожены).

Вот фрагмент кода, в контроллере дружбы, когда он блокирует:

<h2 class="small_v_space">Waiting your approval</h2> 
<ul> 
    <% for user in @user.inverse_friends %> 
    <% if user.friends.exists?(@user) and not @user.friends.exists?(user) %> 
     <li> 
     <%=h user.name %> 
      (<%= link_to "Accept", friendships_path(:friend_id => user), :method => :post %>, 
      <%= link_to "Ignore", friendship_path, :controller => :friendships, :method => :delete %>) 
     </li 
    <% end %> 
    <% end %> 
</ul> 

Проблема заключается в том, что если мне нравится это, метод удаление будет удалить последнее добавленное отношение, вместо один связан с кнопкой игнорирования.

Давайте работать с примером: Вот отношения Я хотел бы уничтожить: user_id: 10 Friend_id: 6 Friendship_id: 18

Я на 'шоу' страница (профиль) пользователя, чей user_id равен 6. Я вижу, что пользователь 10 сделал запрос друга, который я бы проигнорировал. Даже если мне удалось извлечь правильный Friendship_id, выполнив:

<%= link_to "Ignore", friendship_path(Friendship_id), :controller => :friendships, :method => :delete %>) 

Это приводит к «Не удается найти Дружат с ID = 18 [где user_id = 6]»

Кто-нибудь знает, как я мог бы назвать уничтожить действия в правильных отношениях в этом случае? Или я должен действовать иначе?

Большое спасибо за любую подсказку!

РЕДАКТИРОВАТЬ

уничтожить действие контроллера дружбы:

def destroy 
    @friendship = current_user.friendships.find(params[:id]) 
    if @friendship.friend.friends.exists?(current_user) 
     @friendship.destroy 
     flash[:notice] = "Removed friendship." 
    else 
     @friendship.destroy 
     flash[:notice] = "Removed friend request." 
    end 
    redirect_to current_user 
    end 

EDIT 2:

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

Пользователь A посылает запрос друга на пользователя B (A = user, B = friend в экземпляре класса) , Если B принимает запросы, создается другой экземпляр (B = user, A = friend). Если существует как отношение A-> B, так и B-> A, A является другом B. В противном случае запрос остается в ожидании (или может быть проигнорирован, отклонен ...).

+1

Я думаю, что вы слишком усложняете вещи. Я уверен, что для того, чтобы делать то, что вы хотите сделать, все, что вам понадобится, будет моделью друзей и дружбы, а в модели дружбы у вас будет переменная int, называемая статусом, или что-то, что будет иметь разные значения в зависимости от того, будет ли отношения были приняты или нет. Но это не имеет значения. '<% = link_to" Игнорировать ", friendship_path (Friendship_id),: method =>: delete%>' должен работать, не могли бы вы показать действие уничтожения вашего контроллера дружбы? – Ashitaka

+0

@Ashitaka: спасибо за ответ! Я добавил действие destroy в вопросе. Вы правы, есть другие способы сделать это, но я чувствую, что могу многому научиться, имея возможность сделать это таким образом. Проблема заключается в том, что находясь внутри страницы show_ user_6, даже если правая команда friendly_id передана, она терпит неудачу, потому что она говорит «не может найти Friendship_id = 18 WHERE user_id = 6 ... Я хотел бы как-то избавиться от этого user_id = 6 ... Я потратил несколько часов на тонну опций, я чувствую себя немного запутанным сейчас: -/... спасибо в любом случае! – citraL

+0

Хорошо, чтобы решить это, нам нужно немного больше информации. Пожалуйста, покажите свою модель отношений. также, как вы различаете пользователя, который является вашим другом и пользователем, который отправил вам запрос друга? – Ashitaka

ответ

1

Я редактирую весь свой ответ, потому что, я думаю, я нашел суть вашей проблемы. Когда пользователь пытается дружить с кем-то, вы добавляете отношение к этому пользователю, но не добавляете его другому пользователю. SO, current_user.friendships.find(params[:id]) ожидает, что current_user будет иметь дружбу с этим id, но эти отношения не принадлежат ему, а другому пользователю.

Я не уверен, если я сделал это достаточно ясно, но вот моя вторая попытка:

Ваша ссылка должна быть:

<%= link_to "Ignore", friendship_path(:id => friendship_id, :friend_id => user.id), :method => :delete %>) 

И тогда ваши действия:

def destroy 
    potential_friend = User.find(params[:friend_id]) 
    friend_request = potential_friend.friendships.find(params[:id]) 

    friendship = current_user.friendships.find_by_friend_id(potential_friend.id) 
    if friendship.nil?  #Users are not friends and you want to delete the friend request 
    friend_request.destroy 
    flash[:notice] = "Removed friend request." 
    else     #Users are friends and you want to delete the friendship 
    friendship.destroy 
    friend_request.destroy 
    flash[:notice] = "Removed friendship." 
    end 
    redirect_to current_user 
end 

Я не уверен, что вы должны превратить это в пользовательское действие. Как вы можете видеть, это намного больше, чем просто уничтожить один объект.

+0

Спасибо большое Ашитака ... действительно, я думаю, что я подошел к проблеме не так, и ваши несколько комментариев помогли мне получить, когда вы немного потеряли !! ... Я не тестировал вышеупомянутое решение , потому что я ушел в другой вариант, со статусом [ожидающий, одобренный, проигнорированный] ... Большое спасибо! – citraL

+0

Я рад, что ты передумал! Этот подход более адекватен и проще для понимания, поэтому его проще реализовать. Удачи! – Ashitaka

Смежные вопросы