问题
I want to dry up several models by moving shared scopes into a module, something like:
module CommonScopes
extend ActiveSupport::Concern
module ClassMethods
scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
end
end
I also want to create shared specs that test the module. Unfortunately when I try to include the shared scope in my model I get:
undefined method `order' for CommonScopes::ClassMethods:Module
Any ideas? Thanks!
回答1:
You can use instance_eval
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
回答2:
As in rails 4 scope syntax you can simply use a lambda to delay the execution of the code (works in rails 3 too):
module CommonScopes
extend ActiveSupport::Concern
included do
scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") }
end
end
回答3:
Because your scope
method is called immediately when your module is parsed by Ruby and it's not accessible from your CommonScopes
module..
But you can replace your scope call by a class method:
module CommonScopes
extend ActiveSupport::Concern
module ClassMethods
def ordered_for_display
order("#{self.to_s.tableize}.rank asc")
end
end
end
来源:https://stackoverflow.com/questions/7323793/shared-scopes-via-module