Fis*_*ter 5 ruby activerecord ruby-on-rails
我怎么能有像 ActiveRecordscope
这样的东西来修改它所作用的关系?
具体来说,我希望能够做到这一点:
Model.some_scope.fake_destroy_all
Run Code Online (Sandbox Code Playgroud)
fake_destroy_all
我正在尝试创建的功能在哪里。它几乎等同于.update_all(deleted: true)
.
一个弱的替代方案是:
def fake_destroy_all(relation = Model)
relation.update_all(deleted: true)
end
#...
Model.fake_destroy_all(Model.some_scope)
Run Code Online (Sandbox Code Playgroud)
但这并不理想。我想做的是:
scope :fake_destroy_all, update_all(deleted: true)
Run Code Online (Sandbox Code Playgroud)
但这不起作用。
是否有可能做我所描述的事情?
尝试这个:
def self.fake_destroy_all
self.update_all(deleted: true)
end
Run Code Online (Sandbox Code Playgroud)
事实证明,关系保留了所有类方法。作用域也是类方法,它是允许作用域“链接”的确切机制。
因此,与该模型的关系也将具有self
作为关系实例的该方法。
范围语法可能可以像这样修复(现在无法测试,但请注意 lambda 而不是简单的方法调用):
scope :fake_destroy_all, -> { update_all(deleted: true) }
Run Code Online (Sandbox Code Playgroud)
我想,如果不更新 lambda 内部,它会在调用类定义时有效地调用此方法scope
。它确实适用于 simplewhere
类型范围,因为where
没有副作用,它只返回一个适用的过滤器。它被评估一次并保存在方法中以供将来按原样使用。
然而,对于 lambda,执行会一直保持到实际应用范围为止,而不是定义之前。这是必要的,因为update_all
确实有副作用。
如果您指定条件不断变化的范围(最简单的情况是依赖于 ),则同样的技巧很有用,Time.now
它会随着时间的推移而变化,并且每次都需要重新评估。
但是,我建议您使用类方法:作用域更像是过滤器,而这更像是“过滤器执行”。虽然这也可能有效,但范围在语义上适用于不同的用例。
归档时间: |
|
查看次数: |
901 次 |
最近记录: |