Rails STI 使用基础 class 查询所有子 classes
Rails STI query all subclasses using base class
想象一下,我有一个名为生物的 STI table,具有这些子类:
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
我正在尝试对从子类 "Animal" 继承的所有记录进行非常简单的查询。
所以我想要类型= "Cat" 或类型= "Dog" 的记录。我不知道为什么我似乎无法弄清楚。
none 这些选项有效:
- animals = LivingThing.all.map{|r| r.kind_of?("Animal")}
- animals = LivingThing.all.map{|r| r.type == "Animal"}
- animals = LivingThing.kind_of?("Animal")
目前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">]>
你可以这样做:
animals = LivingThing.all.map { |r| r if r.class.superclass.name == 'Animal' }
或:
animals = LivingThing.all.map { |r| r if r.class.superclass == Animal }
这应该会为您提供从 Animal class.[=12 子class编辑的 classes 的所有记录=]
从 rails 4.2(甚至更早)开始,正在做:
Animal.all
将自动呈现一个 sql 调用,例如:
SELECT * FROM "living_things" WHERE "living_things"."type" IN ('Animal', 'Dog', 'Cat')
好了。 :-)
如果您正着手解决这个问题,并且您 运行 而您的 ParentClass.all
没有 return 所有子 class 记录...在 Rails 6.0 中,查询不会自动 return all subclasses.
您需要在父 class 中添加以下内容并指定您想要支持的每个子class:
require_dependency 'subclass_name'
对于Rails7,这里推荐一种稍微不同的方法:https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#single-table-inheritance
想象一下,我有一个名为生物的 STI table,具有这些子类:
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
我正在尝试对从子类 "Animal" 继承的所有记录进行非常简单的查询。 所以我想要类型= "Cat" 或类型= "Dog" 的记录。我不知道为什么我似乎无法弄清楚。
none 这些选项有效:
- animals = LivingThing.all.map{|r| r.kind_of?("Animal")}
- animals = LivingThing.all.map{|r| r.type == "Animal"}
- animals = LivingThing.kind_of?("Animal")
目前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">]>
你可以这样做:
animals = LivingThing.all.map { |r| r if r.class.superclass.name == 'Animal' }
或:
animals = LivingThing.all.map { |r| r if r.class.superclass == Animal }
这应该会为您提供从 Animal class.[=12 子class编辑的 classes 的所有记录=]
从 rails 4.2(甚至更早)开始,正在做:
Animal.all
将自动呈现一个 sql 调用,例如:
SELECT * FROM "living_things" WHERE "living_things"."type" IN ('Animal', 'Dog', 'Cat')
好了。 :-)
如果您正着手解决这个问题,并且您 运行 而您的 ParentClass.all
没有 return 所有子 class 记录...在 Rails 6.0 中,查询不会自动 return all subclasses.
您需要在父 class 中添加以下内容并指定您想要支持的每个子class:
require_dependency 'subclass_name'
对于Rails7,这里推荐一种稍微不同的方法:https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#single-table-inheritance