如果你想要一个数组而不是一个活动记录实例,那么Choco所说的就行了.如果需要活动记录实例,请执行以下操作:
User.where(id: 5).select(:id, :first_name).take
这里有更多信息.我不确定你知道/不知道多少,所以我假设你知道的不是更多而是更少.
我假设你意识到你在上面做的是方法链接——也就是说,你在调用一个方法,然后根据第一个方法的结果调用另一个方法.例如:
User.find_by(id: 5).attributes.slice('id', 'first_name')
您正在调用User
类上的find_by_id
方法.该方法将返回User
类中的instance(即活动记录实例).该实例有一个名为attributes
的方法,您可以调用它.attributes
方法返回Hash
类的一个实例,代表前一个活动记录实例中的字段.Hash
有一个slice
方法,你依次调用它.slice
方法返回Hash
的另一个实例,其中包含指定字段的子集.
因此,需要明确的概念是,当你链接方法时,你并不是在同一件事上调用每个后续方法——你是在链中前一个方法的返回值上调用它.
好了,那么,既然这样:
所有find
个方法都用于查询数据库并返回活动记录模型的单个实例,或者返回包含多个活动记录模型实例的普通rubyarray.
许多其他方法(select
、where
等)不会立即访问数据库,也不会返回活动记录实例.它们都返回ActiveRecord::Relation
的一个实例.ActiveRecord::Relation
有点像一组符合特定条件的潜在记录,你可以给它添加额外的条件.这就像"等待发生的数据库查询"或"可能发生或可能尚未发生的数据库查询".
当你在ActiveRecord::Relation
上调用像where
、order
或select
这样的方法时,它将返回ActiveRecord::Relation
的实例,这意味着你有一个相同类的实例,并且可以很好地从该类链接方法,例如:User.where(name: 'Fred').select(:id, :name).order('name ASC')
您的ActiveRecord::Relation
实例将非常智能,在您调用一个明确表示您现在需要记录的方法之前,不会费心go 访问数据库,比如each
、all
、take
等等.
所以,我走的路比计划的要长,所以我要结束了.以下是我第一次提到的代码,下面有一个详细的、有大量 comments 的解释:
User.where(id: 5).select(:id, :first_name).take
分解:
my_relation = User.where(id: 5)
# The database will not have been hit yet - my_relation
# is a query waiting to happen
my_second_relation = my_relation.select(:id, :first_name)
# The database has STILL not been hit.
# the relation now contains both the conditions
# from the previous my_relation, and the new 'select'
# criteria we specified
my_user = my_second_relation.take
# OK, 'take' means we want the first record
# matching all our criteria,
# so my_second_relation will hit the database
# to get it, and then return an Active Record
# instance (ie, an instance of the User class)
哇!我坚持的时间比预期的要长.希望其中一些有用!