ActiveRecord和ActiveRecord::Relation对象之间的区别

13

我已经搜索过,但无法找到有关ActiveRecord和ActiveRecord::relation对象之间区别的简要说明。

我已经理解了ActiveRecord是通过类似于以下方式查找的单个对象:

User.find(1)

ActiveRecord::Relation 是类似于数组的对象,用于根据某些条件查找。

User.where(id: 1)

我希望了解它们在查询执行方面的区别或更深入地解释它们,以便澄清背后的整个概念。

提前致谢!

3个回答

22

ActiveRecord::Base 的实例是表示数据库中特定行的对象(或可能保存到数据库中)。

ActiveRecord::Relation 的实例是对可以针对数据库运行的查询的表示(但尚未运行)。一旦通过在该 Relation 上调用 to_aeachfirst 等来运行该查询,将返回单个实例或 ActiveRecord::Base 实例数组。


谢谢@spickermann,当我在Rails控制台上尝试时,它显示在Active Record关系的情况下执行了SQL查询,但实际上不应该这样,因为它只是一个表示。你能否解释一下? - power
2
@power:它在控制台中执行,因为控制台调用inspect来输出结果。如果您更改该行以不返回关系(例如User.where(id: 10); nil),则会发现查询未运行。而User.find(10); nil仍将运行查询。 - spickermann
1
这么说是否过于简单了:ActiveRecord::Base代表数据库中的一行,而ActiveRecord::Relation代表将查询数据库的SQL查询?因此,这可能是FinderMethods和QueryMethods之间的根本区别,对吗? - J.R. Bob Dobbs

4
Rails使用activerecord作为标准ORM,但对于单独的activerecord也适用。
简而言之:所有返回多个记录的查询,例如scopes、all、where和joins都会返回一个ActiveRecord::Relation对象。你可以将它们链接在一起,只有当你使用to_sql、first、each、any、to_a、take、last等方法时,查询才会被执行并返回一个ActiveRecord::Base数组。

2
当您使用“find”方法进行记录时,如果该记录不存在于数据库中,则会出现以下错误。
User.find(10)


User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 10]] ActiveRecord::RecordNotFound: Couldn't find User with 'id'=10

如果您按照条件查找用户,但该用户在数据库中不存在,则会像下面一样得到空记录。
User.where(id: 10)


User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ?  [["id", 10]]
 => #<ActiveRecord::Relation []> 

它不会产生任何错误


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接