我可以实现反向关系,因此如果UserA添加了UserB,那么它会在B的配置文件中显示UserA,反之亦然。 但是,如果UserA添加了UserB,我无法弄清楚如何让UserB将UserA作为朋友删除。 我尝试了很多不同的方法,但每次我改变一些东西都会把问题转移到其他地方!我不知道基本问题是否是:
以下代码段:
class FriendshipsController < ApplicationController
def destroy
@friendship = current_user.friendships.find(params[:id])
@friendship.destroy
flash[:notice] = "Removed friendship."
redirect_to current_user
end
在视图中
<% @user.inverse_friends.each do |inverse_friendship| %>
<li>
<%= inverse_friendship.name %>
<%= link_to "remove", @user.inverse_friendships, :method => :delete, :class => "btn-small btn-danger" %><br />
<%= image_tag inverse_friendship.avatar(:thumb) %>
我的模特:
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, class_name: 'User'
attr_accessible :friend_id, :user_id
end
class User < ActiveRecord::Base
has_many :friendships, dependent: :destroy
has_many :friends, through: :friendships
has_many :inverse_friendships, dependent: :destroy, class_name: "Friendship", foreign_key: "friend_id"
has_many :inverse_friends, through: :inverse_friendships, source: :user
路线:
resources :friendships
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users, :controllers => { :registrations => :registrations }
resources :users
答案 0 :(得分:1)
你的主要问题是:
一个。如何定义FriendshipsController销毁方法
您正在寻找friendship
中的current_user.friendships
,但它并不存在。它位于inverse_friendships
。
您需要检查两个关联,或让控制器知道您正在寻找哪一个。后者可能更可取,因为虽然它们是同一类,但它们是不同的资源。这样的事情可能是:
# In routes, route inverse friendships to the same controller, but with a
# different path (I'm routing everything here, you may not need that.)
resources :friendships
resources :inverse_friendships, :controller => 'friendships'
# Then in your friendships controller, use the path to determine which
# collection you're working with:
#
def destroy
@friendship = collection.find(params[:id])
# ...
end
# the other collection methods would use the same collection, if you needed them,
# for example:
def create
@friendship = collection.build(params[:friendship])
# ..
end
protected
# simple case statement here, but you get the idea
def collection
case request.path
when /\/inverse_friendships/ then current_user.inverse_friendships
else current_user.friendships
end
end
最后,在你看来,你会走向一个反向友谊,如:
<%= link_to "remove", inverse_friendship_path(friendship), :method => :delete %>
正常的友谊可以使用较短的形式或完整的命名路线:
<%= link_to "remove", friendship, :method => :delete %>
OR
<%= link_to "remove", friendship_path(friendship), :method => :delete %>
编辑:搜索两个关联。
当然,如果您想保持简单,并且inverse_friends
没有其他用途可以作为单独的资源,那么您可以随时......
def destroy
id, cid = params[:id], current_user.id
# search both associations (two queries)
@friendship = current_user.friendships.find_by_id(id) ||
current_user.inverse_friendships.find(id)
# or query friendship looking for both types
@friendship = Friendship.
where("user_id = ? OR friend_id = ?", cid, cid).find(id)
# ...
end