I know how to use the find
method, and I want to understand the logic of how I get access to it. I'm trying to figure out how ActiveRecord
gives access to the find
method.
As far as I can tell, all models generated inherit from ActiveRecord::Base
. According to the source files, the find
method seems to be located inside the FinderMethods
module. However, I can't find how, or in what way, ActiveRecord::Base
is tied with the FinderMethods
module to give access to the find
method.
If someone could help explain, that would be thankful.
Here it is:
$ grep include.FinderMethods . -r
./activerecord-4.2.8/lib/active_record/relation.rb: include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation
As stated before, the reason you'll find the method find in Relation class is to do stuff like:
# Assume class User < ActiveRecord::Base
u = User.where('1=1').find(1)
If you look deeper:
puts User.where('1=1').class.name
=> "ActiveRecord::Relation"
And as the Relation class includes the FinderMethods module, the find method will be available as an instance method of the Relation class so you can do the mentioned call:
User.where('1=1').find(1)
Now, if you wonder why you can do this:
User.find(1)
You'll have to look at this line in the class ActiceRecord::Base
extend Querying
And in if you see the ActiveRecord::Querying module you will find this line:
delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
So what happens here is that ActiveRecord::Base will have the class method find because its extending Querying who is delegating the find method through the all method defined in the Relation class. The key here is understanding what delegates do and here's the place to do that:
FinderMethods are part of ActiveRecord::Relation not ActiveRecord::Base.
ActiveRecord::Relation is the query that will run on the database while ActiveRecord:Base is the instance of the row/s from ActiveRecord::Relation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.