从ActiveRecord查询返回类型

如果我要从ActiveRecord调用中获取Relation,Array或其他类型的内容,会让我知道什么? 我知道我可以在控制台中键入.class并弄清楚,但是调用本身有什么能让我知道我要的是什么吗?

你知道,Rails有时会对你说谎 – 所有魔术师都会这样做:)

Rails允许您通过链接has_many关联来构建复杂查询。 此function的核心是一堆XXXAssocation(如HasManyAssociation )类。 当您在has_many关联上调用.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_/ } 

HasManyAssociation实例的undefs(隐藏)方法(除了少数,正如你在正则表达式中看到的那样)然后使用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 

因此, HasManyAssociation实例决定自己要处理什么以及需要通过隐藏数组完成什么( class方法不是HasManyAssociation感兴趣的,所以它将在这个隐藏数组上调用。结果当然是Array ,是一个小小的欺骗)。

根据我认为重要的知识,这是我的看法。 它主要来自内存,并且通过一些小的控制台实验从头顶开始,所以我确定如果它能够通过它可以得到改善。 欢迎评论,并要求。

 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 

所以重要的是,

  • 您可以链接范围和查询方法,但只能直到第一个或全部。 在第一次或全部之后,您无法调用更多范围和查询方法。
  • 当您调用all时,您将获得一个Result Array。 一些Array方法已被重新定义为对数据库起作用,因此如果要对返回的数组进行操作,请调用to_a。 一个例子是count,如果在结果数组上调用,它将查询数据库,如果再次查询的数组,将在数组中有多少条记录。