你能不能让我知道Active Record如何调用'哪里有'当我执行User.where(id: 1)
?
我正在检查Active Record的功能以阅读源代码并通过pry停止进程。
我可以看到当我执行User.where(id: 1)
时,过程进行到
rails/activerecord/lib/active_record/querying.rb
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
:where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly,
:having, :create_with, :distinct, :references, :none, :unscope, :merge, to: :all
'其中'被委派给:全部。
因此,它去了
rails/activerecord/lib/active_record/scoping/named.rb
def all
if current_scope
current_scope.clone
else
default_scoped
end
end
我不明白这一部分。为什么会这样? 委托可以设置为类方法吗?我虽然可以委托给类变量,实例变量。
在scoping / named.rb all方法中的default_scope之后,进程转到rails/activerecord/lib/active_record/relation/query_methods.rb
def where(opts = :chain, *rest)
if :chain == opts
WhereChain.new(spawn)
elsif opts.blank?
self
else
spawn.where!(opts, *rest)
end
end
为什么呢?是不是where
被委托给:all
?它如何回到where
(relation / query_methods.rb)?
答案 0 :(得分:4)
我不明白这一部分。为何选择
all
?
由于:
User.where(id: 1)
相当于:
User.all.where(id: 1)
此委派是为了简化API,在没有明确指定的情况下添加对all
的隐式调用。
如何回到
where
(relation / query_methods.rb)?
请记住,这是委托,而不是别名。所以,从那以后:
User.all
返回:
User.default_scoped
这意味着,实际上,这是正在构建的方法链:
User.where
--> User.all.where
--> User.default_scoped.where
由于User.default_scoped
是User::ActiveRecord_Relation
个对象,因此#where
的定义确实在rails/activerecord/lib/active_record/relation/query_methods.rb
中定义,如下:
def where(opts = :chain, *rest)
if :chain == opts
WhereChain.new(spawn)
elsif opts.blank?
self
else
spawn.where!(opts, *rest)
end
end
......但这只是故事的开始。我们还远远没有为查询构建实际的SQL。
Here is a series of blog posts如果您感兴趣的话可以深入了解 - 但我认为这超出了单个StackOverflow答案的范围。