Rails 5中如何获取ActiveRecord类的自定义作用域列表?
获取Rails 5模型的自定义作用域列表
嘿,这个需求很实用!遗憾的是,Rails 5并没有内置一个直接返回所有自定义作用域名称的custom_scopes方法,但我们可以轻松自己实现这个功能,而且方案很灵活。
实现思路
Rails的作用域(scope)本质上是通过scope方法为模型类添加了对应的类方法,同时所有定义过的作用域都会被记录在模型类的scopes哈希中——这个哈希的键就是作用域的名称(符号形式),值则是对应的lambda表达式。
具体实现
你可以直接在目标模型(比如MyRecord)中添加一个类方法,或者把它放到抽象基类ApplicationRecord里让所有模型共享:
1. 仅在单个模型中实现
class MyRecord < ActiveRecord::Base scope :custom_scope_one, ->() { where(id: 4) } scope :custom_scope_two, ->() { where(id: 4) } scope :custom_scope_three, ->() { where(id: 4) } def self.custom_scopes # 获取当前模型的所有作用域,排除父类继承来的作用域 scopes.keys - superclass.scopes.keys end end
2. 让所有模型都能用(推荐)
如果你的项目里所有模型都继承自ApplicationRecord,把这个方法放到基类里会更高效:
class ApplicationRecord < ActiveRecord::Base self.abstract_class = true def self.custom_scopes scopes.keys - superclass.scopes.keys end end
测试效果
现在调用MyRecord.custom_scopes,就会准确返回你想要的结果:
MyRecord.custom_scopes # => [:custom_scope_one, :custom_scope_two, :custom_scope_three]
补充说明
- 如果你只想获取当前类自身定义的作用域,上面的方法会自动排除父类(比如
ApplicationRecord或者ActiveRecord::Base)中定义的作用域。 - 如果你的模型没有继承自自定义的抽象基类,直接用
scopes.keys - ActiveRecord::Base.scopes.keys也能达到目的,不过前者的扩展性更好。
内容的提问来源于stack exchange,提问作者jdfolino
相关产品推荐
相关产品推荐

