【问题标题】:Rails 3 friendship model : how to ignore a friend request?Rails 3 友谊模型:如何忽略好友请求?
【发布时间】:2012-04-05 05:58:00
【问题描述】:

我有传统的友谊模式:

用户模型有:

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>

问题是,如果我这样做,删除方法将删除最后添加的关系,而不是链接到忽略按钮的关系。

我们来看一个例子这是我想破坏的关系: 用户 ID:10 朋友编号: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

编辑 2:

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

用户 A 向用户 B 发送好友请求(A=用户,B=类实例中的好友)。如果 B 接受请求,则创建另一个实例(B=用户,A=朋友)。如果同时存在关系 A->B 和 B->A,则 A 是 B 的朋友。否则,请求保持未决(或可以忽略、拒绝...)。

【问题讨论】:

  • 我认为你把事情复杂化了。我很确定要做你想做的事,你需要的只是一个朋友和友谊模型,在友谊模型中,你会有一个名为 status 的 int 变量,或者根据是否有不同值的东西这段关系是否被接受。但这无关紧要。 &lt;%= link_to "Ignore", friendship_path(Friendship_id), :method =&gt; :delete %&gt; 应该可以了,你能展示一下你的友谊控制器的破坏动作吗?
  • @Ashitaka:感谢您的回复!我在问题中添加了破坏动作。你是对的,还有其他方法可以做到这一点,但我觉得能够通过这种方式做到这一点,我可以学到很多东西。问题是在 user_6 的显示页面内,即使传递了正确的friendship_id,它也会失败,因为它说“找不到 Friendship_id=18 WHERE user_id =6 ...我想以某种方式摆脱这个 user_id =6 ...我花了几个小时尝试大量的选项,现在我感到有点困惑:-/ ...无论如何,谢谢!
  • 好的,为了解决这个问题,我们需要更多信息。请展示您的关系模型。另外,您如何区分作为您朋友的用户和向您发送好友请求的用户?
  • @Ashitaka:添加了关系模型并在 EDIT2 中回答了您的问题。但我认为你是对的,我走错了路,我认为在友谊模型中使用状态字段(接受,忽略,待定)会更好......但如果你看到我应该如何做原来的方式,我很高兴知道;-)
  • 查看我编辑的答案!也许这次我做对了。

标签: ruby-on-rails relationship destroy


【解决方案1】:

我正在编辑我的整个答案,因为我想我找到了你的问题的要点。当用户尝试与某人成为朋友时,您会向该用户添加关系,但不会将其添加到其他用户。所以,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

我不确定您是否应该将此转换为自定义操作。如您所见,它所做的不仅仅是销毁单个对象。

【讨论】:

  • 非常感谢Ashitaka ...确实,我认为我以错误的方式解决了这个问题,当你有点迷失时,你的几个帮助cmets很高兴!!...我没有测试上述解决方案,因为我进入了另一个选项,状态为[待定,批准,忽略]...非常感谢!
  • 很高兴你改变了主意!该方法更充分且更易于理解,因此更易于实施。祝你好运!
猜你喜欢
  • 2012-08-22
  • 2023-04-04
  • 1970-01-01
  • 2012-10-28
  • 2011-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多