Ruby on rails 通过模块共享作用域?
我想通过将共享作用域移动到一个模块中来干涸几个模型,比如:Ruby on rails 通过模块共享作用域?,ruby-on-rails,activerecord,rspec,scope,activemodel,Ruby On Rails,Activerecord,Rspec,Scope,Activemodel,我想通过将共享作用域移动到一个模块中来干涸几个模型,比如: module CommonScopes extend ActiveSupport::Concern module ClassMethods scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc") end end 我还想创建测试模块的共享规范。不幸的是,当我尝试在模型中包含共享范围时,我得到了: undefined
module CommonScopes
extend ActiveSupport::Concern
module ClassMethods
scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
end
end
我还想创建测试模块的共享规范。不幸的是,当我尝试在模型中包含共享范围时,我得到了:
undefined method `order' for CommonScopes::ClassMethods:Module
有什么想法吗?谢谢 因为Ruby解析模块时会立即调用
scope
方法,并且无法从CommonScopes
模块访问该方法
但您可以用类方法替换范围调用:
module CommonScopes
extend ActiveSupport::Concern
module ClassMethods
def ordered_for_display
order("#{self.to_s.tableize}.rank asc")
end
end
end
你可以用
在rails 4中,您可以简单地使用lambda延迟代码的执行(在rails 3中也适用):
你不认为现在应该首选lambda吗?@mdemolin我认为在rails 4中不使用lambda调用
scope
是不可取的。正是我所说的:)(但我认为这只是目前首选的语法,还没有被否决)这也有点错误,因为它取消了扩展ActiveSupport::Concern的意义。作用域应位于块中,如included do。。。结束
因为这是ActiveRecord::Concern的一部分,或者我们不应该费心扩展它,因为上面的self.included
语法内置于每个Ruby模块中,与ActiveSupport::Concern无关。理想情况下,我们选择一种或另一种方式,因为ActiveSupport::Concern会处理我们在本答案示例中重新实现的样板代码。这适用于Rails 3和Rails 4,正如mdemolin的回答一样
module CommonScopes
extend ActiveSupport::Concern
def self.included(klass)
klass.instance_eval do
scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
end
end
end
module CommonScopes
extend ActiveSupport::Concern
included do
scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") }
end
end