0

Lets say I have a model named Animal with attribute species.

I intend to subclass Tiger from Animal, which attribute species is "tiger", how to define it so that

Animal.where(:species => 'tiger').where(:age => 12)

can be written as

Tiger.where(:age => 12)?

My attempted solution:

class Tiger < Animal    
  def self.inherited(child)
    child.instance_eval do
      def type
        "tiger"
      end
    end
    super
  end
end

References: 1. http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/ 2. http://www.alexreisner.com/code/single-table-inheritance-in-rails

mu is too short
  • 426,620
  • 70
  • 833
  • 800
Lee Chun Hoe
  • 728
  • 11
  • 19

1 Answers1

0

Whereas I have understand your problem you just want to implement simple STI.

I have tried it and it worked for me. Create a base class Animal in which Animal table attributes will be species, name and age.

class Animal < ApplicationRecord
  self.inheritance_column = :species

  def self.species
    %w(Lion Tiger)
  end
end

Inherited classes.

class Lion < Animal
end
class Tiger < Animal
end

Try this hope it will solve your problem.

nitanshu verma
  • 261
  • 3
  • 8
  • The species column is in format of small letter, i.e. the subclass Tiger is being identified as Animal with species "tiger" (small letter t). What is the way to specify that? – Lee Chun Hoe Mar 21 '18 at 07:58
  • As per the convention this isn't possible as they are classes and they can be denoted as Tiger and Lion rather than tiger and lion. but still they will be saved as "Lion" and "Tiger" fetch that and then you can turn it "tiger" – nitanshu verma Mar 21 '18 at 13:26
  • Is there configuration (over convention) way of doing this? Because existing data were "tiger" in small case and I don't want to change that. – Lee Chun Hoe Mar 22 '18 at 08:45
  • If you want to store the inherited model name to be stored in lowercase follow this link https://gist.github.com/sumskyi/1381880 – nitanshu verma Mar 22 '18 at 10:39