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!
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
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
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