如何在Ruby on Rails中访问.find()方法?

时间:2018-05-10 00:27:57

标签: ruby-on-rails

我知道如何使用find方法,我想了解我如何访问它的逻辑。我试图找出ActiveRecord如何访问find方法。

据我所知,所有生成的模型都继承自ActiveRecord::Base。根据源文件,find方法似乎位于FinderMethods模块内。但是,我无法找到ActiveRecord::Base如何或以何种方式与FinderMethods模块绑定,以便访问find方法。

如果有人可以帮忙解释,那就太感恩了。

3 个答案:

答案 0 :(得分:1)

这是:

$ grep include.FinderMethods . -r
./activerecord-4.2.8/lib/active_record/relation.rb:    include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation

答案 1 :(得分:1)

如前所述,您找到该方法的原因在于 关系类是做类似的事情:

# Assume class User < ActiveRecord::Base
u = User.where('1=1').find(1)

如果你看得更深:

puts User.where('1=1').class.name
=> "ActiveRecord::Relation"

由于Relation类包含FinderMethods模块,find方法将作为Relation类的实例方法使用,因此您可以执行上述调用:

User.where('1=1').find(1)

现在,如果你想知道为什么你可以这样做:

User.find(1)

您必须在ActiceRecord :: Base类中查看此行

extend Querying

如果你看到ActiveRecord :: Querying模块,你会发现这一行:

delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all

所以这里发生的是ActiveRecord :: Base将具有find方法find,因为它通过Relation类中定义的all方法扩展了查询谁委托find方法。这里的关键是了解代表的行为,以及这里的地方:

https://apidock.com/rails/Module/delegate

答案 2 :(得分:0)

FinderMethods是ActiveRecord :: Relation而非ActiveRecord :: Base的一部分。

https://github.com/rails/rails/blob/375a4143cf5caeb6159b338be824903edfd62836/activerecord/lib/active_record/relation.rb#L18

ActiveRecord :: Relation是将在数据库上运行的查询,而ActiveRecord:Base是ActiveRecord :: Relation的实例。