New*_*ria 12 activerecord types lazy-loading ruby-on-rails
我正在使用Rails 3.2.0
比方说我有:
class Comment < ActiveRecord::Base
has_many :articles
end
c1 = Comment.last
Run Code Online (Sandbox Code Playgroud)
然后
c1.articles.class
# => Array
c1.articles.where('id NOT IN (999999)').class
# => ActiveRecord::Relation
Run Code Online (Sandbox Code Playgroud)
为什么关联的结果不是一种类型ActiveRecord::Relation?
它显然是/ 在某个时候:
c1.articles.to_orig
# undefined method `to_orig' for #<ActiveRecord::Relation:0x007fd820cc80a8>
c1.articles.class
# => Array
Run Code Online (Sandbox Code Playgroud)
某些评估作用于ActiveRecord :: Relation对象,但检查该类会给出不同的类型.
特别是,当merge用于连接多个查询时,这会破坏构建延迟加载的查询.
And*_*all 15
这是一个ActiveRecord::Relation,但Rails故意骗你.您可以在方法调用中看到这一点,并通过调用继续查看它ancestors,其中包括一系列ActiveRecord类:
c1.articles.ancestors.select { |c| c.to_s =~ /ActiveRecord/ }.size #=> 35
Run Code Online (Sandbox Code Playgroud)
这表明它不是一个Array.
这是因为你在调用时得到的c1.articles是ActiveRecord::Associations::CollectionProxy*,它取消定义class(以及许多其他方法).这意味着,class通过被授权的method_missing,这将其发送到target.我们可以看到,target这里的类实际上是Array:
c1.articles.target.class #=> Array
Run Code Online (Sandbox Code Playgroud)
那就是c1.articles.class来自哪里.不过,它是一个ActiveRecord::Relation.
*我们可以ActiveRecord::Associations::CollectionProxy通过class在相关对象上调用Ruby的原始方法来验证它确实是一个问题:Object.instance_method(:class).bind(c1.articles).call.这是一个很好的技巧来验证对象不是试图假装是一个不同的类.
| 归档时间: |
|
| 查看次数: |
3127 次 |
| 最近记录: |