如何将类方法转换为两个模型之间的关系?

Posted

技术标签:

【中文标题】如何将类方法转换为两个模型之间的关系?【英文标题】:How do I convert a class method into a relation between two models? 【发布时间】:2021-08-18 18:30:10 【问题描述】:

我有BasePlan 那个has_many Plans 的模型。我们使用BasePlan 中的类方法按字母顺序对关联的Plans 进行排序,我需要将其重构为两个模型之间的关联。

BasePlan类:

has_many :plans, ->  extending BuildWithAccount ,
           inverse_of: :base_plan, dependent: :destroy

Plan类:

belongs_to  :base_plan

BasePlan 按字母顺序排列计划的类方法:

  def order_plans_alphabetically
    plans.order(code: :asc)
  end

我在BasePlan 中创建了一个新关联,如下所示:

has_many :alphabetically_ordered_plans, ->  order_plans_alphabetically , class_name: "Plan"

结果:

NameError: undefined local variable or method `order_plans_alphabetically' for #<Plan::ActiveRecord_Relation:0x00005593e3876460>

我还尝试在现有关联的 lambda 中包含类方法,导致 100 多个测试失败,所以我认为这也不是可行的方法。

将类方法重构为两个模型之间的关系的有效方法是什么?

【问题讨论】:

【参考方案1】:
has_many :alphabetically_ordered_plans, 
  ->  order(code: :asc) # short for Plan.order(code: :asc) , 
  class_name: "Plan"

评估 lambda 的上下文不是 BasePlan 类),而是您关联的类(计划)。如果你真的想使用一个作用域(基本上只是一个类方法),你需要把它放在那个类中:

class Plan < ApplicationRecord
  belongs_to :base_plan
  scope :order_by_code, -> order(code: :asc) 
end

class BasePlan < ApplicationRecord
  has_many :alphabetically_ordered_plans, 
    ->  order_by_code ,
    class_name: "Plan"
end

【讨论】:

以上是关于如何将类方法转换为两个模型之间的关系?的主要内容,如果未能解决你的问题,请参考以下文章

将类数组转换为数组的方法

当类依赖于隐式时,是否存在将类转换为Object的惯用方法?

rose中如何画类图,具体步骤是啥呀

将类隐式转换为 int 的正确方法是啥?

Bigquery:将类转换为 Bigquery TableSchema

如何将类作为方法的参数传递? [复制]