Ruby on rails 有很多只以一种方式加入自己的同事吗

Ruby on rails 有很多只以一种方式加入自己的同事吗,ruby-on-rails,activerecord,ruby-on-rails-4,rails-activerecord,Ruby On Rails,Activerecord,Ruby On Rails 4,Rails Activerecord,我有一个用户模型,我想通过使用has\u和\u-belies\u-to\u-many的自连接来连接到它自己。我让它几乎像预期的那样工作,只是我希望它将两个用户以两种方式关联起来 我的用户类: class User < ActiveRecord::Base ... has_and_belongs_to_many :friends, autosave: true, class_name: 'User', join_table: :friendship

我有一个用户模型,我想通过使用has\u和\u-belies\u-to\u-many的自连接来连接到它自己。我让它几乎像预期的那样工作,只是我希望它将两个用户以两种方式关联起来

我的用户类:

class User < ActiveRecord::Base
  ...
  has_and_belongs_to_many :friends,
      autosave: true,
      class_name: 'User',
      join_table: :friendships,
      foreign_key: :user_id,
      association_foreign_key: :friend_user_id
  ...
end
class用户
我的迁移:

class CreateFriendships < ActiveRecord::Migration
  def self.up
    create_table :friendships, id: false do |t|
      t.integer :user_id
      t.integer :friend_user_id
    end

    add_index(:friendships, [:user_id, :friend_user_id], :unique => true)
    add_index(:friendships, [:friend_user_id, :user_id], :unique => true)
  end

  def self.down
    remove_index(:friendships, [:friend_user_id, :user_id])
    remove_index(:friendships, [:user_id, :friend_user_id])
    drop_table :friendships
  end
end
class-CreateFriendshipstrue)
添加索引(:friendships,[:friends\u user\u id,:user\u id],:unique=>true)
结束
def自动关闭
删除索引(:friendships,[:friends\u user\u id,:user\u id])
删除索引(:friendships,[:user\u id,:friends\u user\u id])
放下桌子:友谊
结束
结束
我的问题是:

user1 = User.find(1)
user2 = User.find(2)

user1.friends << user2
user1.reload.friends.exists?(user2) # true
user2.reload.friends.exists?(user1) # false <- My problem
user1=User.find(1)
user2=User.find(2)
user1.friends你也可以做

user2.friends << user1

user2.friends不那么粗俗的方法是在自己的方法中建立友谊:

class User < ActiveRecord::Base
  def make_friend(user)
    # TODO: put in check that association does not exist
    self.friends << user
    user.friends << self
  end
end

更为粗俗的一种方法是使用
ActiveRecord::Associations
方法重写。例如,
has_和_属于_many的
method
collection我意识到这是可能的,但并不像我所希望的那样,它实际上是双向的。我不记得Ryan Bates是否解决了这个问题,但看看你是否提出了与我当时几乎相同的解决方案,所以我可能会使用它
def add_friend(user)self.friends您也可以查看我在SO上发布的类似问题。
user1.make_friend(user2)
# should set both friends know about each other
class User < ActiveRecord::Base
  attr_accessor :reversed  # we use it to avoid stack level too deep issue
  has_and_belongs_to_many :friends, ... do
    def << (new_friend)
      reversed = true
      # it should not trigger on our friend record as self.reversed is true
      new_friend.friends << self unless new_friend.reversed
      super new_friend
    end     
  end
end