ruby-on-rails - 双向 self 参照关联

标签 ruby-on-rails ruby activerecord

我有一个包含 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 attendee_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 - 双向 self 参照关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35641668/

相关文章:

javascript - 使用 Ajax 更新 Rails 中的 'like' 计数

ruby-on-rails - 如何从精炼厂主页中删除页面标题 [RAILS]

ruby - 在 Ruby 中测试设备相关代码

ruby-on-rails - 未定义的方法,为什么?

ruby-on-rails - ActiveRecord:如何克隆嵌套关联?

ruby - 使用 Marshal 将 Sqlite 内存数据库转储到磁盘

ruby-on-rails - Slack 传入 Webhook API

javascript - JS 文件双重包含在 Rails 应用程序中

ruby-on-rails - 返回率 |如何根据日期查找下一个和上一个

ruby-on-rails - 随着 Rails 4.2.3 改变 where_values 的行为,我如何获得 where_values 的有效 SQL?