2011-12-20 9 views
5

モンゴイドは、habtmに.pushを付けて出荷され、両方向にhabtm関係を設定します。 deleteは#関連するレコードを削除しますが、私が見た関係のみを削除する方法はありません。これを行うより良い方法はありますか?HABTM mongoidフォロー/フォロワー

一意性を保証する良い方法はありますか?

has_and_belongs_to_many :following, {class_name: 'User', inverse_of: :followers, inverse_class_name: 'User'} 
    has_and_belongs_to_many :followers, {class_name: 'User', inverse_of: :following, inverse_class_name: 'User'} 

    def follow!(user) 
    self.following.push(user) # this pushes the inverse as well 
    self.following_ids.uniq! 
    self.save! 
    user.follower_ids.uniq! 
    user.save! 
    end 

    def unfollow!(user) 
    self.following.delete(user.id) 
    self.save! 
    user.followers.delete(self.id) 
    user.save! 
    end 

答えて

18

次のコードは、(mongoidの2.3.x以降)私のためにうまく働いた:

class User 
    include Mongoid::Document 

    field :name, type: String 

    has_and_belongs_to_many :following, class_name: 'User', inverse_of: :followers, autosave: true 
    has_and_belongs_to_many :followers, class_name: 'User', inverse_of: :following 

    def follow!(user) 
    if self.id != user.id && !self.following.include?(user) 
     self.following << user 
    end 
    end 

    def unfollow!(user) 
    self.following.delete(user) 
    end 
end 

ノーinverse_class_name、無通話の保存、特別な取り扱いが、自己、以下を除いて。

なぜなら、モンゴイドは関係文に追加されていなければ自動的にdependent: nullifyを使用するからです。 autosave: trueでは、リレーションシップの更新が保存されます(フォロワーを直接変更しないため、フォローアップのためにのみ必要です)。自動保存オプションを使用しないと、メソッドで保存呼び出しを追加する必要があります。これは、mongoidは関係更新を自動的に保存しないためです(2.0.0.x以降)。

私はブロックとしてif節を置くので、例外処理(else raise FooException)でそれを変更することができます。

.delete(user)もいいですが、モンゴイドの文書にも記載されています:http://mongoid.org/docs/relations/referenced/n-n.html( "DEPENDENT BEHAVIOR"までスクロールしてください)。

+0

ここには素晴らしいものがあります。しかし、私は以前にいくつかのテストを行い、誤っていない限り、同じトラップに落ちました:.delete(user)はデータベースからユーザを削除し、nullifyは現在削除されたユーザに対して行われた参照を指します。 –

+0

.deleteはユーザーオブジェクト自体ではなく、.followingハッシュ上にあります。 docのように "単一の子関係を孤立させる"と言います。それは仕事をして、私はそれをテストし、それは動作します。 – asaaki

+0

'!self.following.include?(user)'というコードは、以下の関係の中にあまりユーザーがいないのに、10Kユーザーのようになっている人には涼しいです.../ –