使用模型 it belongs_to 的属性在 has_many 关联中设置模型属性的最全面方法是什么?

What is the most comprehensive way to set an attribute on a model in a has_many association using an attribute of the model it belongs_to?

我有两个 ActiveModel,MultivariateExperiment has_many MultivariateExperimentVariant。反之,一个MultivariantExperimentVariantbelongs_to一个MultivariateExperiment.

MultivariateExperiment 具有属性 experiment_name

MultivariantExperimentVariant 具有属性 nameweighting.

我希望变体的 name 采用 experiment_name_0experiment_name_1 等格式。 例如,给定以下 MultivariateExperiment:

mve = MultivariateExperiment.create({ experiment_name: 'user_signup' })

我想要一种程序化的方式来让相关变体成为:

mve.multivariate_experiment_variants.create({ weighting: 1 }) # expected name: "user_signup_0"

mve.multivariate_experiment_variants.create({ weighting: 1 }) # expected name: "user_signup_1"

mve.multivariate_experiment_variants.create({ weighting: 2 }) # expected name: "user_signup_2"

我最初考虑将它放在 after_commit 回调中,但在代码审查中被告知要避免它,因为该回调是 finnicky(不确定为什么)

我查看了其他一些回调,但其中 none 似乎足以涵盖创建关联的无数种方式,例如:

# 1st approach
mve.multivariate_experiment_variants.create({ weighting: 1 })

# 2nd approach
variant = MultivariateExperimentVariant.create({ weighting: 1 })
mve << variant
mve.save

# 3rd approach
mve.multivariate_experiment_variants.build({ weighting: 1 })
mve.save


# etc. etc.

那么,鉴于创建关联的各种方法,是否有任何机制或方法可以使用它所属的模型的属性成功地计算 has_many 关系中模型的属性?

MultivariateExperimentVariant 模型中你可以做...

after_save :set_name

private

def set_name
  # Assuming you have a required belongs_to
  update(name: "#{multivariate_experiment.name}_#{multivariate_experiment.multivariate_experiment_variants.length - 1}")
end

除非指定 on: 条件

,否则您不想使用 after_commit
after_commit :set_name, on: [:create, :update]

否则会在记录销毁后尝试设置name

旁注: 相反,检查索引可能会更好...

 update(name: "#{multivariate_experiment.name}_#{multivariate_experiment.multivariate_experiment_variants.index(self)}")