为什么Rails的模型关联结果不自然的ActiveRecord ::关系? [英] Why are Rails model association results not naturally ActiveRecord::Relations?
问题描述
我用Rails 3.2.0
I'm using Rails 3.2.0
让我们说我有:
class Comment < ActiveRecord::Base
has_many :articles
end
c1 = Comment.last
然后
c1.articles.class
# => Array
c1.articles.where('id NOT IN (999999)').class
# => ActiveRecord::Relation
为什么是一个关联的结果的的没有的键入的ActiveRecord ::关系
?
这显然是/是的在某些时候的:
c1.articles.to_orig
# undefined method `to_orig' for #<ActiveRecord::Relation:0x007fd820cc80a8>
c1.articles.class
# => Array
若干评价作用于一个ActiveRecord ::关联对象,但检查类给出了不同的类型。
Certain evaluations act upon an ActiveRecord::Relation object, but inspecting the class gives a different type.
特别是,这打破建筑懒加载查询时使用合并
来Concat的多个查询。
Particularly, this breaks building lazy-loaded queries when using merge
to concat multiple queries.
推荐答案
这是一个的ActiveRecord ::关联
,而 Rails是故意骗你。你可以看到这个已经在方法调用,并继续通过调用的祖先
,其中包括ActiveRecord的类摆看看吧:
It is an ActiveRecord::Relation
, but Rails is intentionally lying to you. You can see this already in the method calls, and continue to see it by calling ancestors
, which includes a slew of ActiveRecord classes:
c1.articles.ancestors.select { |c| c.to_s =~ /ActiveRecord/ }.size #=> 35
这表明它非常的没有的的阵列
。
这是因为你在取回时调用 c1.articles
是<一个href="https://github.com/rails/rails/blob/v3.2.9/activerecord/lib/active_record/associations/collection_proxy.rb"><$c$c>ActiveRecord::Associations::CollectionProxy$c$c>*,其中<一个href="https://github.com/rails/rails/blob/v3.2.9/activerecord/lib/active_record/associations/collection_proxy.rb#L39">undefines 类
(以及许多其他方法)。这意味着类
通过<一个被委派href="https://github.com/rails/rails/blob/v3.2.9/activerecord/lib/active_record/associations/collection_proxy.rb#L77">its 的method_missing
,该<一href="https://github.com/rails/rails/blob/v3.2.9/activerecord/lib/active_record/associations/collection_proxy.rb#L89">sends为目标
。正如我们所看到的,类目标
在这里,事实上,阵列
:
This happens because what you’re getting back when calling c1.articles
is an ActiveRecord::Associations::CollectionProxy
*, which undefines class
(along with many other methods). This means that class
gets delegated via its method_missing
, which sends it to target
. As we can see, the class of target
here is, in fact, Array
:
c1.articles.target.class #=> Array
这就是 c1.articles.class
从何而来。然而,它的是的的的ActiveRecord ::关联
。
That is where c1.articles.class
comes from. Nevertheless, it is an ActiveRecord::Relation
.
<子>
* 我们可以验证它确实是一个的ActiveRecord ::协会:: CollectionProxy
通过调用Ruby的原类
有问题的对象方法: Object.instance_method(:类).bind(c1.articles).CALL
。这是一个很好的技巧,以验证对象是不是想pretend是一个不同的类。的
* We can verify that it is indeed an ActiveRecord::Associations::CollectionProxy
by calling Ruby’s original class
method on the object in question: Object.instance_method(:class).bind(c1.articles).call
. This is a nice trick to verify that the object is not trying to pretend to be of a different class.
这篇关于为什么Rails的模型关联结果不自然的ActiveRecord ::关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!