views:

214

answers:

2

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?

A: 
class Account < Foo::Bar::Base
end

module Foo
  module Bar
    class Base < ::ActiveRecord::Base
      def self.abstract_class?
        true
      end
    end
  end
end

That works fine for me. It results in table name "accounts" as it have to be.

Thomas Boerger
A: 

Try this:


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

Or:


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

Croplio