Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: How to effectively use self.inherited

I have an AbstractRecord model from which some of the concrete models (which have their own tables) descend. Following is the inheritance.

AbstractRecord < ActiveRecord::Base
Blog < AbstractRecord
Post < AbstractRecord
....
....

In order for Rails to look for the proper tables if there is inheritance, API docs say to define a class method abstract_class? that returns true so that rails won't look for its table. In my case, in order for rails to look for blogs table (instead of abstract_records table, which is typically the case as in STI) I defined method abstract_class? in AbstractRecord that returns true. All the queries seems to work fine. But I see whenever I instantiate Blog, rails shows it as Blog (abstract) in the console as its parent class returns true. In order to avoid this, I could again define abstract_class? that returns false in Blog class.

But I was thinking instead of defining abstract_class? in all the child models, if I could somehow make use of self.inherited and define that method in AbstractClass itself. I tried to use several approaches (following) none seems to work.

class AbstractRecord < ActiveRecord::Base
 def self.abstract_class?
    true
 end

 def self.inherited(subclass)
  super
  subclass.instance_eval do
   define_method(:abstract_class?) { false }
  end
 end  
end

class AbstractRecord < ActiveRecord::Base
 def self.abstract_class?
    true
 end

 def self.inherited(subclass)
  super
  subclass.class_eval do
   define_method(:abstract_class?) { false }
  end
 end  
end

class AbstractRecord < ActiveRecord::Base
 def self.abstract_class?
    true
 end

 def self.inherited(subclass)
  super
  subclass.instance_eval do
   def abstract_class?
    false
   end
  end
 end  
end

class AbstractRecord < ActiveRecord::Base
 def self.abstract_class?
    true
 end

 def self.inherited(subclass)
  super
  subclass.class_eval do
   def abstract_class?
    false
   end
  end
 end  
end

Any advise on what I am doing wrong is appreciated?

like image 855
Dharam Gollapudi Avatar asked Dec 07 '25 18:12

Dharam Gollapudi


1 Answers

Try this:


def self.inherited(subclass)
  super
  def subclass.abstract_class?
    false
  end
end

Or:


def self.inherited(subclass)
  super
  subclass.class_eval do
    def self.abstract_class? 
  # You lost the 'self' part, so you had just defined an instant method for the subclass
      false
    end
  end
 end

like image 106
Croplio Avatar answered Dec 10 '25 11:12

Croplio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!