gpt4 book ai didi

ruby-on-rails - 双向自指关联

转载 作者:数据小太阳 更新时间:2023-10-29 09:01:04 25 4
gpt4 key购买 nike

我有一个包含 2 个模型的简单数据库:

class Fighter < ActiveRecrod::Base
has_many :fights
has_many :opponents, through :fights
end

class Fight < ActiveRecord::Base
belongs_to :fighter
belongs_to :opponent, class_name: 'Fighter'
end`

我应该添加什么才能让它工作:

a = Fighter.create
b = Fighter.create
a.opponents << b
b.fights <- should return a value`

a.fights 应该返回新创建的 Fight

b.fights 也应该返回新创建的 Fight

目前只有a.fights返回值

我想到了这样的想法:

class Fight < ActiveRecord::Base
belongs_to :fighter
belongs_to :opponent, class_name: 'Fighter'
after_create :create_association

def create_association
Fighter.find(opponent_id).fights << self
end
end

但是从 Fight 调用另一个模型似乎不对。

我还尝试在 Fighter 中重载 has_man :fights 以便它接受 lambda

has_many :fights, -> { where("fighter_id = ? OR opponent_id =?", self.id, self.id) 但我经常收到错误 - 参数数量错误(0 代表 2)

经过一番研究,我知道我应该使用双向自引用关联,类似于:Bidirectional self referential associations

但是当按照这个操作时,我会在表 Fight 中收到两条战斗记录。一个与一名战士相关联,另一个与第二名战士相关联。

我将不胜感激有关如何解决此问题的帮助或提示

最佳答案

如果您不想定义反向关系(如 this Railscast 中所建议),我认为您无法避免每次都产生两场战斗。您使用 after_create 的想法可行,只需添加对手而不是战斗本身,如下所示:

class Fight < ActiveRecord::Base
belongs_to :fighter
belongs_to :opponent, class_name: 'Fighter'

after_create :create_association

def create_association
opponent = Fighter.find(opponent_id)
unless opponent.opponents.include?(fighter)
Fighter.find(opponent_id).opponents << fighter
end
end
end

反向关系在性能和存储方面会更好,但使用起来并不无缝:

class Fighter < ActiveRecord::Base
has_many :fights
has_many :opponents, through: :fights

has_many :inverse_fights, :class_name => "Fight", :foreign_key => "opponent_id"
has_many :inverse_opponents, :through => :inverse_fights, :source => :fighter
end

从这里开始,如果您想要一个战士的所有对手,您应该执行 a_fighter.opponents + a_fighter.inverse_opponents

关于ruby-on-rails - 双向自指关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35641668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com