使用 Rails 关联而不是实例方法

Posted

技术标签:

【中文标题】使用 Rails 关联而不是实例方法【英文标题】:Using Rails association instead of instance method 【发布时间】:2021-10-23 02:51:38 【问题描述】:

我现在有以下内容:

class Supply < ApplicationRecord
  def movements
    SupplyMovement.around_supply(self)
  end
end

class SupplyMovement < ApplicationRecord
  belongs_to :from_supply, class_name: 'Supply', optional: true
  belongs_to :to_supply, class_name: 'Supply', optional: true
    
  scope :around_supply, ->(supply)  where('from_supply_id = :supply OR to_supply_id = :supply', supply: supply.id) 

end

我想在 Supply 类中使用 :movements 关联而不是 movements 方法。我该怎么做?

【问题讨论】:

【参考方案1】:

这实际上是不可能的。

在 ActiveRecord 中,每个 has_one / has_many 关联对应于另一个表上的单个外键列。无法指定外键可以是两列之一的关联。

你可以做的是声明两个关联:

class Supply < ApplicationRecord
  has_many :movements_as_source, 
    class_name: 'SupplyMovement',
    foreign_key: :from_supply_id
  has_many :movements_as_destination, 
    class_name: 'SupplyMovement',
    foreign_key: :to_supply_id
end

但是,这并不能真正让您将其视为同质集合。

或者您可以更改表格布局,以便只有一个外键:

class Supply < ApplicationRecord
  has_many :movements
end

class SupplyMovement < ApplicationRecord
  self.inheritance_column = 'not_type'
  belongs_to :supply
  enum :type, [:destination, :source]
end

这会让您急切地加载关联,但代价是您需要两倍的行数和更高的复杂性。

【讨论】:

以上是关于使用 Rails 关联而不是实例方法的主要内容,如果未能解决你的问题,请参考以下文章

Rails:从另一个模型调用或委托实例方法

在 Ruby on Rails 中测试模型实例是不是为“空”的最佳方法是啥?

Ruby/Rails - 为啥自我关联条件取决于创建时间?

为啥在 python 中使用类方法而不是实例方法

为啥我使用@classmethod 而不是普通的实例方法[重复]

ruby 类方法,实例方法内省ruby / rails