【发布时间】:2017-05-21 00:15:25
【问题描述】:
我有以下模型和关联:
SuccessCriterion
has_many :requirements
has_many :findings, through: :requirements
Requirement
belongs_to :success_criterion
has_many :findings
Finding
belongs_to :requirement
has_one :success_criterion, through: :requirement
- 每个结果都可以有一个状态
critical - 如果一个需求至少有一个关键发现,那么它的状态也是关键
- 如果成功标准至少有一个关键要求,那么它的状态也是关键
所以临界状态是继承的。
在显示成功标准列表时,我想显示其状态是否为关键。为此,我通过遍历所有需求并再次遍历所有发现并搜索至少一个关键发现来计算状态。
这需要大量的数据库查询,所以我正在考虑在成功标准中缓存状态,并且每次我添加/修改/删除结果时,都应该在成功标准中更新状态。
最好的方法是什么?我想过像这样的after_save 过滤器:
model Finding
belongs_to :requirement
has_one :success_criterion, through: :requirement
after_save :update_success_criterion_status
private
def update_success_criterion_status
if status.critical?
success_criterion.update_attribute :status, :critical
else
success_criterion.calculate_status! # Iterate through all findings and look for at least one critical
end
end
end
在开发中,我猜这会很好用。
但是测试呢?对于单元测试成功标准,我必须为每个测试提供必要的关联,否则after_save 过滤器会崩溃。这意味着每次测试都会产生大量开销。
当然,我可以做一些 hacky 之类的事情
after_save :update_success_criterion_status, unless: -> { Rails.env.test? }
但我认为这不是一个好方法。
有没有更好的方法来做到这一点?还是我走错了路?也许甚至有宝石可以处理这样的事情(修改相关资源的属性)?
附言
类似的要求是反缓存深度关联元素的可能性。假设我们有另一个模型,例如
Project
has_many :success_criteria
当我们想知道一个项目中有多少发现时,我们必须通过成功标准、要求和发现来计算它们。计数器缓存也可以在这里节省大量查询。但是需要处理所有关联模型的大量创建/更新/删除内容以更新计数器缓存...
【问题讨论】:
-
我的回答对你有帮助吗?如果没有,你介意评论一下为什么不?
-
感谢您的全面帖子。我还不能看它,但我肯定会很快的。
标签: ruby-on-rails database caching model