ruby-on-railsruby-on-rails-4single-table-inheritance

Rails STI query all subclasses using base class


Imagine I have this STI table called living things with these such subclasses:

class LivingThing < ActiveRecord::Base
end

class Animal < LivingThing
end

class Plant < LivingThing
end

class Fungus < LivingThing
end

class Cat < Animal
end

class Dog < Animal
end

I am trying to get a very simple query of all records that INHERIT from subclass "Animal". So I want records wher type= "Cat" or type= "Dog". I don't know why I can't seem to figure this out.

none of these options work:

- animals = LivingThing.all.map{|r| r.kind_of?("Animal")}
- animals = LivingThing.all.map{|r| r.type == "Animal"}
- animals = LivingThing.kind_of?("Animal")

currently LivingThing.all =

 => #<ActiveRecord::Relation [#<Cat id: 2,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">, #<Dog id: 3,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">,#<Cat id: 4,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">, #<Cat id: 5,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">, #<Rose id: 6,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">, #<Oak id: 7,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">, #<Mushroom id: 6,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">, #<Ringworm id: 8,  status: 1,  created_at: "2016-03-25 00:57:20", updated_at: "2016-03-25 00:57:20">]> 

Solution

  • You can do this:

    animals = LivingThing.all.map { |r| r if r.class.superclass.name == 'Animal' }
    

    or:

    animals = LivingThing.all.map { |r| r if r.class.superclass == Animal }
    

    This should give you all the records of classes that are subclassed from the Animal class.