ruby-on-rails - 使用它所属模型的属性在 has_many 关联中设置模型属性的最全面方法是什么?
问题描述
我有两个 ActiveModel,MultivariateExperiment
其中has_many
MultivariateExperimentVariant
. 相反,一个MultivariantExperimentVariant
belongs_to
a MultivariateExperiment
。
MultivariateExperiment
有一个属性experiment_name
。
MultivariantExperimentVariant
具有属性name
和weighting
。
我希望变体name
的格式experiment_name_0
为 ,experiment_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 (不知道为什么)
我查看了其他一些回调,但它们似乎都不够全面,无法涵盖可以创建关联的无数方式,例如:
# 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
after_commit
除非您指定on:
条件,否则您不想使用
after_commit :set_name, on: [:create, :update]
否则,它会在记录被销毁后尝试设置名称。
旁注:最好改为检查索引......
update(name: "#{multivariate_experiment.name}_#{multivariate_experiment.multivariate_experiment_variants.index(self)}")
推荐阅读
- java - 在失败的测试用例上截屏时出现错误,并且它没有附加到扩展报告
- reactjs - Reactjs - 登录重定向但有无效的挂钩调用
- debugging - 内核模块的 objdump 中指令位置的两个数字是什么?
- java - Eclipse Okhttp 错误 - java.lang.NoSuchFieldError: Companion
- python - Tensorflow 2.3 保存和加载模型的问题
- opencv - OpenCL-Kernel 只渲染图像的每 2 行
- kubernetes - k8s sidecar收集的日志会不会丢失?
- java - 可以具有不同数据类型的字段的 Spring Java POST 端点
- c - c程序用已经设置的4位密码检查用户输入的密码
- nginx - 如何在windows中重新加载nginx