Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared scopes via module?

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!

like image 376
Allyl Isocyanate Avatar asked Sep 06 '11 17:09

Allyl Isocyanate


2 Answers

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
like image 82
mdemolin Avatar answered Nov 19 '22 12:11

mdemolin


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
like image 17
Gazler Avatar answered Nov 19 '22 12:11

Gazler