Reputation: 2363
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">]>
Upvotes: 2
Views: 3206
Reputation: 1595
In case you are landing on this question and you're running and your ParentClass.all
is not returning all of the subclass records... In Rails 6.0, the query not automatically return all subclasses.
You'll need to add the following in the parent class and specify each subclass that you would like to support:
require_dependency 'subclass_name'
See https://guides.rubyonrails.org/v6.0/autoloading_and_reloading_constants_classic_mode.html#autoloading-and-sti for more details
For Rails 7, a slightly different approach is recommended here: https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#single-table-inheritance
Upvotes: 2
Reputation: 8845
As of rails 4.2 (maybe even before), doing:
Animal.all
will automatically render an sql call something like:
SELECT * FROM "living_things" WHERE "living_things"."type" IN ('Animal', 'Dog', 'Cat')
So there you have it. :-)
Upvotes: 1
Reputation: 34338
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.
Upvotes: 1