Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: dynamically define class method based on parent class name within module/concern

I want to dynamically generate a class method in a Mixin, based on the class name that include this Mixin.

Here is my current code:

module MyModule  
  extend ActiveSupport::Concern  

  # def some_methods  
  #   ...  
  # end  

  module ClassMethods  

    # Here is where I'm stuck...
    define_method "#{self.name.downcase}_status" do  
      # do something...  
    end  

  end  
end  

class MyClass < ActiveRecord::Base  
  include MyModule  
end  

# What I'm trying to achieve:
MyClass.myclass_status

But this give me the following method name:

MyClass.mymodule::classmethods_status  

Getting the base class name inside the method definition works (self, self.name...) but I can't make it works for the method name...

So far, I've tried

define_method "#{self}"
define_method "#{self.name"
define_method "#{self.class}"
define_method "#{self.class.name}"
define_method "#{self.model_name}"
define_method "#{self.parent.name}"

But none of this seems to do the trick :/

Is there any way I can retrieve the base class name (not sure what to call the class that include my module). I've been struggling with this problem for hours now and I can't seem to figure out a clean solution :(

Thanks!

like image 503
cl3m Avatar asked Feb 05 '13 11:02

cl3m


1 Answers

You can't do it like that - at this point it is not yet known which class (or classes) are including the module.

If you define a self.included method it will be called each time the module is included and the thing doing the including will be passed as an argument. Alternatively since you are using AS::Concern you can do

included do 
  #code here is executed in the context of the including class
end
like image 87
Frederick Cheung Avatar answered Sep 24 '22 16:09

Frederick Cheung