Calling an overriden scope from an included concern in the overriding scope

Viewed 160

So basically I have a class MyClass that includes a concern MyConcern with an included scope 'foo'. I want to be able to override the scope 'foo' in MyClass, but still be able to call the overriden scope in MyConcern.

module MyConcern {
  extend ActiveSupport::Concern

  included do
    scope :foo, lambda{ |x|
      puts "Hello"
    }
  end
}

class MyClass {
  include MyConcern

  scope :foo, lambda{ |x|
    MyConcern.foo(x)
    puts " World"
  }
}

So when I call @myClass.foo(1) where @myClass is an instance of MyClass, I should be able to see "Hello World" printed out.

A similar thread that I could find was Calling super in overriden scope defined in concern, but unfortunately I am unable to use regular class methods in my case.

Any help will be appreciated!

2 Answers

When you use included inside MyConcern, it happens after "include YourModule" is called on a class. But doesn't change anything on MyConcern. If you want to have a superclass method, try

module MyConcern
  extend ActiveSupport::Concern
  def self.foo
    puts "Hello"
  end
end

Now you can call MyConcern.foo

The point of a concern is to avoid duplication and share methods between classes. So you don't need to call the Module to call the included method that you've included in the class. Also, if you redefine the concern's method in the class, than it will override the concern's method. Here's closer to what I think you're trying to do, but note you need a new method name in the class.

module MyConcern
  extend ActiveSupport::Concern

  included do
    def self.foo # don't pass unused arguments so x is removed here
      puts "Hello"
    end
  end

end

Then in your class:

 class MyClass 
  include MyConcern

  # don't define foo but a new method name    
  def self.fool(x)
    foo
    puts "#{x} World"
  end

end

Now you can call:

MyClass.fool('bar')

Also note your particular example is useless for the scope methods instead just define class methods as I've shown here.

Related