Ruby on rails 返回所有包含duck、Ruby的对象

Ruby on rails 返回所有包含duck、Ruby的对象,ruby-on-rails,ruby,Ruby On Rails,Ruby,我希望返回包含duck的对象的所有实例 例如: 我怎样才能打电话: 所以它返回[a,b] 目前,我被困在: ActiveRecord::Base.subclasses.select{| type | type.祖先。include?FruitDuck}.map&:all.flatte 然而,这似乎很脆弱 puts ObjectSpace.each_object(FruitDuck).to_a 返回所有现有文件,即当前在内存中实例化的文件 puts ObjectSpace.each_object

我希望返回包含duck的对象的所有实例

例如:

我怎样才能打电话:

所以它返回[a,b]

目前,我被困在:

ActiveRecord::Base.subclasses.select{| type | type.祖先。include?FruitDuck}.map&:all.flatte

然而,这似乎很脆弱

puts ObjectSpace.each_object(FruitDuck).to_a
返回所有现有文件,即当前在内存中实例化的文件

puts ObjectSpace.each_object(Class).select { |c| c < FruitDuck }.flat_map(&:all)
应该为您提供所有的FruitDuck类,然后对其调用all,假设所有FruitDuck都是ActiveRecord模型,则为您提供数据库中的所有实例。如果没有,则需要包括此限制。

使用Mixin调用类上的所有 要在包含FruitDuck的每个类上调用all,这将起作用:

ObjectSpace.each_object(FruitDuck).flat_map &:all
但是,它并不能真正实现您想要的功能,因为ActiveRecord调用Apple.all只会返回已持久化到数据库中的苹果。它也不会返回包含mixin的对象的变量名

检查Mixin的实例变量 要查找混合了模块的内存中变量的名称,出于作用域的原因,必须使用实例变量而不是局部变量。然后,您可以执行以下操作:

@a = Apple.new
@b = Banana.new

instance_variables.select { |v| instance_variable_get(v).class < FruitDuck }
#=> [:@a, :@b]

我假设您希望检索持久化记录,因为:

Apple.all  #=> returns [a]
Banana.all #=> returns [b]
您可以使用在类包含模块时调用的回调:

module FruitDuck
  def self.included(mod)
    @included ||= []
    @included << mod
  end

  def self.all
    @included.flat_map(&:all)
  end
end

请注意,FruitDuck.all将执行多个查询,并在数组中返回连接的结果。因此,与Apple.all或Banana.all不同,它不会返回ActiveRecord::Relation。

您发布的代码肯定与您所说的不一样。a=Apple.new将不会由Apple.all返回。ActiveRecord的类级方法查询数据库。它们不查询内存中的对象。查找特定类型对象的所有实例与ActiveRecord提供的功能无关。如果您实际上想要一个ActiveRecord解决方案,那么您需要单表继承,它将允许您使用BaseClass.all查询基类的所有实例。
Apple.all  #=> returns [a]
Banana.all #=> returns [b]
module FruitDuck
  def self.included(mod)
    @included ||= []
    @included << mod
  end

  def self.all
    @included.flat_map(&:all)
  end
end