Ruby on rails ActiveRecord查询的返回类型

Ruby on rails ActiveRecord查询的返回类型,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,如果我要从ActiveRecord调用中获取关系、数组或其他类型,有什么可以让我知道?我知道我可以在控制台中键入.class并找出答案,但调用本身是否有什么东西可以让我知道我的要求?以下是我的看法,大致上是我认为需要知道的内容。它主要来自于记忆,并且在我的脑海中进行了一些控制台实验,所以我确信如果这一点得到传播,它会得到改进。欢迎评论,并请发表意见 Derived ActiveRecord class --> Record Instance find Derived ActiveRe

如果我要从ActiveRecord调用中获取关系、数组或其他类型,有什么可以让我知道?我知道我可以在控制台中键入.class并找出答案,但调用本身是否有什么东西可以让我知道我的要求?

以下是我的看法,大致上是我认为需要知道的内容。它主要来自于记忆,并且在我的脑海中进行了一些控制台实验,所以我确信如果这一点得到传播,它会得到改进。欢迎评论,并请发表意见

Derived ActiveRecord class --> Record Instance
  find

Derived ActiveRecord class | Relation --> Relation
  where, select, joins, order, group, having, limit, offset, a scope

Derived ActiveRecord class | Relation --> Record Instance
  find

Derived ActiveRecord class | Relation --> Result Array
  all

Result Array --> Array
  to_a
所以重要的是

您可以链接作用域和查询方法,但只能链接到first或all。首先,您不能调用更多的作用域和查询方法。 调用all时,将得到一个结果数组。一些数组方法已被重新定义以作用于数据库,因此如果要对返回的数组进行操作,请调用_a。例如count,如果在结果数组上调用,它将查询数据库,以了解如果再次查询该数组,该数组中会有多少记录。
你知道,Rails有时对你撒谎——所有魔术师都会这样做:

Rails允许您通过链接多个关联来构建复杂的查询。此功能的核心是一组类似于HasmanaSociation类的XXX关联类。 当你调用一个有很多关联的.class时,你的调用实际上应用于HasManyAssociation实例。但神奇的开始是:

# collection_proxy.rb
instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to|proxy_/ }
Rails undefs隐藏HasManyAssociation实例的方法(除了少数方法),正如您在正则表达式中看到的那样,然后使用delegation和method_missing将调用传递给某个底层数组(如果您试图获取记录),或者在链接关联时传递给关联本身:

  delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from,
           :lock, :readonly, :having, :pluck, :to => :scoped 

  delegate :target, :load_target, :loaded?, :to => :@association

  delegate :select, :find, :first, :last,
           :build, :create, :create!,
           :concat, :replace, :delete_all, :destroy_all, :delete, :destroy, :uniq,
           :sum, :count, :size, :length, :empty?,
           :any?, :many?, :include?,
           :to => :@association

  def method_missing(method, *args, &block)
    match = DynamicFinderMatch.match(method)
    if match && match.instantiator?
      send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
        proxy_association.send :set_owner_attributes, r
        proxy_association.send :add_to_target, r
        yield(r) if block_given?
      end
    end

    if target.respond_to?(method) || (!proxy_association.klass.respond_to?(method) && Class.respond_to?(method))
      if load_target
        if target.respond_to?(method)
          target.send(method, *args, &block)
        else
          begin
            super
          rescue NoMethodError => e
            raise e, e.message.sub(/ for #<.*$/, " via proxy for #{target}")
          end
        end
      end

    else
      scoped.readonly(nil).send(method, *args, &block)
    end
  end

因此,HasmanyAsociation实例决定自己要处理什么,需要通过hidden array类方法完成什么不是HasmanyAsociation感兴趣的,因此它将在这个隐藏数组上被调用。当然,结果将是数组,这是一个小骗局。

了解您试图对结果执行的操作会有所帮助。