1

私のプロジェクトでは、自己参照の関連付けがあります。

私はユーザーモデルを持っています:

class User < ActiveRecord::Base
  has_many :relationships, :dependent => :destroy
  has_many :peers, :through => :relationships
end

そして関係モデル:

class Relationship < ActiveRecord::Base
  belongs_to :user
  belongs_to :peer, :class_name => "User"
end

2人のユーザーが互いにピアである場合、データベースには明らかに2つのレコードがあります。

1人のユーザーが関係を終了することを選択した場合、関係の片側だけでなく、両方のレコードを破棄するようにしたいと思います。

コントローラにリレーションシップを2回ロードする(リレーションシップの両側に1回ずつ)よりも、これを実行するためのより良い方法はありますか?

4

1 に答える 1

1

これを行うことができるいくつかの方法

まず、削除後のトリガーです。これは、データベースにとらわれないという誤った約束を信じている場合、かなり物議を醸す方法ですが、機能します。つまり、old.peer_idとold.user_idを調べてから、削除しますが、役割を逆にします。このルートをたどりたい場合は、トリガーの実装方法としてデータベースのマニュアルを参照してください。

2番目の方法は、after_destroy コールバックです。

after_destroy do |record| 
  other = Relationship.find_by_user_id_and_peer_id(record.peer_id, record.user_id)
  other.destroy if other
end

もう1つ、おそらくもっと抜本的な対策は、モデルを作り直して、関係の両側がデータベース内の1つのレコードによってモデル化されるブール許容フィールドを持つようにすることです。ここで、レコードには制約があり(peer_id, user_id) = (user_id, peer_id)ます。そうすれば、両側を削除したり、レコードが重複したりすることを心配する必要がなくなります。

于 2011-01-06T23:06:59.173 に答える