私はitems
テーブルを持っています。私は別のペアでいくつかを作成する必要があります。私のスキーマには、equivalent_id
が含まれています。これは、パートナーが存在する場合、パートナーのIDを保管します。同じモデルのレコードペアの関係を設定する
モデルに関係を設定するにはどうすればよいですか? has_one
またはbelongs_to
と言うのは奇妙に思えます。なぜなら、ペア内の項目のどちらも他の概念的な方法で支配的ではないからです。
私はitems
テーブルを持っています。私は別のペアでいくつかを作成する必要があります。私のスキーマには、equivalent_id
が含まれています。これは、パートナーが存在する場合、パートナーのIDを保管します。同じモデルのレコードペアの関係を設定する
モデルに関係を設定するにはどうすればよいですか? has_one
またはbelongs_to
と言うのは奇妙に思えます。なぜなら、ペア内の項目のどちらも他の概念的な方法で支配的ではないからです。
has_one
を使用すると、has_one :equivalent, :class_name => "Item"
と表示され、わかりやすく表示されます。
1対1の自己参照および双方向の関連付けは、多対多または多対多の自己参照および双方向の関連付けであっても(驚くほど)複雑です。
ただ明確にする:
:他の点では
revolver = Item.create name: 'revolver'
pistol = Item.create name: 'pistol'
revolver.equivalent = pistol
revolver.equivalent # => pistol
pistol.equivalent # => revolver
、あなたが項目にequivalent_id設定した場合は、所有者は」equivalent_idも設定する必要があります。
1対1の関連付けは、insert_sql
とdelete_sql
オプションを受け入れません。だから、それほどかわいいです。しかし、(IMO)これを行うにはクリーンな方法は次のとおりです。
class Item < ActiveRecord::Base
has_one :equivalent, class_name: 'Item', foreign_key: 'equivalent_id'
def add_equivalent(other)
self.equivalent = other
other.equivalent = self
end
def remove_equivalent
equivalent.equivalent = nil
self.equivalent = nil
end
end
この方法で、あなたが行うことができます:
revolver = Item.create name: 'revolver'
pistol = Item.create name: 'pistol'
revolver.add_equivalent(pistol)
revolver.equivalent # => pistol
pistol.equivalent # => revolver
pistol.remove_equivalent
pistol.equivalent # => nil
revolver.equivalent # => nil
編集:
をセキュリティで保護するには、クリーンアップする必要がありますあなたが同等のものを追加するたびにその関係。それは意味:
revolver.equivalent # => pistol
pistol.equivalent # => revolver
revolver.add_equivalent(gun)
revolver.equivalent # => gun
pistol.equivalent # => nil
あなたがそのようなことを行うことができます。
def add_equivalent(other)
remove_equivalent if equivalent
...
end
あなたは、既存の同等のものを置き換えるために同等=をオーバーライドすることができます。そこにはただ一つしかないと仮定します。 – rkb
@rkbそれがとてもシンプルだったら私はとても幸せだろう。私は私の答えで詳細を飛ばしましたが、試してみてください。私は確かに良い答えに投票します。トランザクションは(特に新しいものを作成する前に既存の関係をクリアすることになる)ときどき気まぐれです。もう一度、それは私の意見でそれを行う**最もクリーンな方法です**。 – Damien