Ruby on rails rails 4中的相互关系

Ruby on rails rails 4中的相互关系,ruby-on-rails,ruby,rails-activerecord,rails-models,Ruby On Rails,Ruby,Rails Activerecord,Rails Models,我正试图让我的应用程序中的用户通过好友请求彼此成为好友,但我对这种关系的运作方式有点困惑。。。当一个用户创建了友谊并被另一个用户接受时,我希望两个用户都能看到友谊(显然) 我希望实现一个实现,使我能够执行类似于以下的操作: user1 friend requests user2 user2 accepts user1.friends now contains user2 user2.friends now contains user1 @user = User.find params[:i

我正试图让我的应用程序中的用户通过好友请求彼此成为好友,但我对这种关系的运作方式有点困惑。。。当一个用户创建了友谊并被另一个用户接受时,我希望两个用户都能看到友谊(显然)

我希望实现一个实现,使我能够执行类似于以下的操作:

user1 friend requests user2
user2 accepts
user1.friends now contains user2
user2.friends now contains user1
@user   = User.find params[:id]
@friend = User.find params[:friend_id]

@user.friends << @friend
#config/routes.rb
resources :users do
  resources :friendships, only: [:index, :destroy, :update], path_names: { destroy: "remove", update: "accept" }
end

#app/controllers/Frienships_controller.rb
class FriendshipsController < ApplicationController
  def index
    @user       = User.find params[:user_id]
    @friendship = @user.friendships
  end

  def update
    @user       = User.find params[:user_id]
    @friendship = @user.friendships.find params[:id]
    @friendship.accept
  end

  def destroy
    @user       = User.find params[:user_id]
    @friendship = @user.friendships.find params[:id]
    @friendship.decline
  end
end

#app/views/friendships/index.html.erb
<%= @friendships.pending.each do |friendship| %>
  <%= link_to "Accept", user_friendships_path(user, friendship), method: :put %>
  <%= link_to "Decline", user_friendships_path(user, friendship), method: :delete %>
<% end %>
到目前为止,我已经知道了一些关于nested has__很多的奇怪事情:通过关系

class User < ActiveRecord::Base
 has_many :friendships
 has_many :friends, :class_name => "User", :through => :friendships
end

class Friendship < ActiveRecord::Base
 has_many :users, :limit => 2
end
class用户“用户”,:通过=>:友谊
终止
类友谊2
终止

这是一个可行的实施方案吗?如果没有,我可以改变/改进什么?如果可能的话,我希望避免两行代表一个关系。

您要查找的是一个has\u和\u属于\u多个关系,但属于同一个表,类似于的详细描述。但是,由于您希望这种关系是双向的(“我的朋友也都是我的朋友”),您有两种选择:

  • 使用单个联接表,每行链接两个用户ID,但为每个用户ID插入两行

    # no need for extra columns on User
    class User < ActiveRecord::Base
      has_many :friendships
      has_many :friends, through: :friendships
    end
    
    # t.belongs_to :user; t.belongs_to :friend
    class Friendship < ActiveRecord::Base
      belongs_to :user
      belongs_to :friend, class_name: "User"
    end
    
    u1 = User.create!
    u2 = User.create!
    u3 = User.create!
    
    # make users 1 and 2 friends
    u1.friendships.create(friend: u2)
    u2.friendships.create(friend: u1)        
    
    # make users 2 and 3 friends
    u2.friendships.create(friend: u3)
    u3.friendships.create(friend: u2)        
    
    # and now, u1.friends returns [u1],
    # u2.friends returns [u1, u3] and
    # u3.friends returns [u2].
    
    编辑该文件,使其看起来像:

    class CreateFriendships < ActiveRecord::Migration
      create_table :friendships do |t|
        t.belongs_to :user
        t.belongs_to :friend
        t.timestamps
      end
    end
    
    POST /friendships?friend_id=42
    
    请求将如下所示:

    class CreateFriendships < ActiveRecord::Migration
      create_table :friendships do |t|
        t.belongs_to :user
        t.belongs_to :friend
        t.timestamps
      end
    end
    
    POST /friendships?friend_id=42
    

    然后,只要您想查找用户的好友,就可以引用当前用户。好友。

    您要查找的是一个has\u和\u属于\u多个关系,但属于同一个表,类似于中的详细描述。但是,由于您希望这种关系是双向的(“我的朋友也都是我的朋友”),您有两种选择:

  • 使用单个联接表,每行链接两个用户ID,但为每个用户ID插入两行

    # no need for extra columns on User
    class User < ActiveRecord::Base
      has_many :friendships
      has_many :friends, through: :friendships
    end
    
    # t.belongs_to :user; t.belongs_to :friend
    class Friendship < ActiveRecord::Base
      belongs_to :user
      belongs_to :friend, class_name: "User"
    end
    
    u1 = User.create!
    u2 = User.create!
    u3 = User.create!
    
    # make users 1 and 2 friends
    u1.friendships.create(friend: u2)
    u2.friendships.create(friend: u1)        
    
    # make users 2 and 3 friends
    u2.friendships.create(friend: u3)
    u3.friendships.create(friend: u2)        
    
    # and now, u1.friends returns [u1],
    # u2.friends returns [u1, u3] and
    # u3.friends returns [u2].
    
    编辑该文件,使其看起来像:

    class CreateFriendships < ActiveRecord::Migration
      create_table :friendships do |t|
        t.belongs_to :user
        t.belongs_to :friend
        t.timestamps
      end
    end
    
    POST /friendships?friend_id=42
    
    请求将如下所示:

    class CreateFriendships < ActiveRecord::Migration
      create_table :friendships do |t|
        t.belongs_to :user
        t.belongs_to :friend
        t.timestamps
      end
    end
    
    POST /friendships?friend_id=42
    
    然后,只要您想查找用户的好友,就可以参考当前用户。好友。

    您可以使用:

    --

    这将为用户添加一个新的
    友谊
    ,其默认
    状态
    设置为
    pending
    。设置
    @user.friends
    关联,以便在通话中仅显示
    已接受的
    好友

    因此,您将能够执行以下操作:

    user1 friend requests user2
    user2 accepts
    user1.friends now contains user2
    user2.friends now contains user1
    
    @user   = User.find params[:id]
    @friend = User.find params[:friend_id]
    
    @user.friends << @friend
    
    #config/routes.rb
    resources :users do
      resources :friendships, only: [:index, :destroy, :update], path_names: { destroy: "remove", update: "accept" }
    end
    
    #app/controllers/Frienships_controller.rb
    class FriendshipsController < ApplicationController
      def index
        @user       = User.find params[:user_id]
        @friendship = @user.friendships
      end
    
      def update
        @user       = User.find params[:user_id]
        @friendship = @user.friendships.find params[:id]
        @friendship.accept
      end
    
      def destroy
        @user       = User.find params[:user_id]
        @friendship = @user.friendships.find params[:id]
        @friendship.decline
      end
    end
    
    #app/views/friendships/index.html.erb
    <%= @friendships.pending.each do |friendship| %>
      <%= link_to "Accept", user_friendships_path(user, friendship), method: :put %>
      <%= link_to "Decline", user_friendships_path(user, friendship), method: :delete %>
    <% end %>
    
    #config/routes.rb
    资源:用户可以
    资源:友谊,仅:[索引,:销毁,:更新],路径名称:{销毁:“删除”,更新:“接受”}
    终止
    #app/controllers/Frienships\u controller.rb
    类友谊控制器<应用程序控制器
    def索引
    @user=user.find参数[:user\u id]
    @友情=@user.friends
    终止
    def更新
    @user=user.find参数[:user\u id]
    @友谊=@user.friendships.find参数[:id]
    @友谊,接受
    终止
    def销毁
    @user=user.find参数[:user\u id]
    @友谊=@user.friendships.find参数[:id]
    @友谊。衰落
    终止
    终止
    #app/views/friendships/index.html.erb
    
    您可以使用:

    --

    这将为用户添加一个新的
    友谊
    ,其默认
    状态
    设置为
    pending
    。设置
    @user.friends
    关联,以便在通话中仅显示
    已接受的
    好友

    因此,您将能够执行以下操作:

    user1 friend requests user2
    user2 accepts
    user1.friends now contains user2
    user2.friends now contains user1
    
    @user   = User.find params[:id]
    @friend = User.find params[:friend_id]
    
    @user.friends << @friend
    
    #config/routes.rb
    resources :users do
      resources :friendships, only: [:index, :destroy, :update], path_names: { destroy: "remove", update: "accept" }
    end
    
    #app/controllers/Frienships_controller.rb
    class FriendshipsController < ApplicationController
      def index
        @user       = User.find params[:user_id]
        @friendship = @user.friendships
      end
    
      def update
        @user       = User.find params[:user_id]
        @friendship = @user.friendships.find params[:id]
        @friendship.accept
      end
    
      def destroy
        @user       = User.find params[:user_id]
        @friendship = @user.friendships.find params[:id]
        @friendship.decline
      end
    end
    
    #app/views/friendships/index.html.erb
    <%= @friendships.pending.each do |friendship| %>
      <%= link_to "Accept", user_friendships_path(user, friendship), method: :put %>
      <%= link_to "Decline", user_friendships_path(user, friendship), method: :delete %>
    <% end %>
    
    #config/routes.rb
    资源:用户可以
    资源:友谊,仅:[索引,:销毁,:更新],路径名称:{销毁:“删除”,更新:“接受”}
    终止
    #app/controllers/Frienships\u controller.rb
    类友谊控制器<应用程序控制器
    def索引
    @user=user.find参数[:user\u id]
    @友情=@user.friends
    终止
    def更新
    @user=user.find参数[:user\u id]
    @友谊=@user.friendships.find参数[:id]
    @友谊,接受
    终止
    def销毁
    @user=user.find参数[:user\u id]
    @友谊=@user.friendships.find参数[:id]
    @友谊。衰落
    终止
    终止
    #app/views/friendships/index.html.erb
    
    我只是有点困惑如何使用它,我会为创建方法和迁移做些什么???我只是有点困惑如何使用它,我会为创建方法和迁移做些什么???真的很有帮助,但这是一个API,我只是有点困惑,如果我使用Desive,当前用户指的是当前用户,那么控制器的创建操作会是什么样子。。。我知道如何创建友谊,但如何正确地将它与用户和即将成为朋友的人联系起来->也不确定迁移将如何进行look@Riptyde4:请参阅我对答案的编辑。我为选项1添加了具体的代码示例,这是我推荐的解决方案。你真是个圣人!谢谢,这很好地解决了问题,真的很有帮助,但这是一个API,我只是有点困惑,如果我使用的是Desive,当前用户指的是当前用户,那么控制器的创建操作会是什么样子。。。我知道如何创建友谊,但如何正确地将它与用户和即将成为朋友的人联系起来->也不确定迁移将如何进行look@Riptyde4:请参阅我对答案的编辑。我为选项1添加了具体的代码示例,这是我推荐的解决方案。你真是个圣人!谢谢,这会把事情弄清楚的