发现与找到由于与在哪里

我是新来的,我发现有很多方法可以找到一张唱片:

  1. find_by_<columnname>(<columnvalue>)
  2. find(:first, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>).first

看起来它们最终都生成了完全相同的 SQL。此外,我相信同样的道理也适用于查找多个记录:

  1. find_all_by_<columnname>(<columnvalue>)
  2. find(:all, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>)

是否有一个经验法则或建议使用哪一个?

204055 次浏览

您列表中的两个 # 2都不被推荐使用,但是您仍然可以使用 find(params[:id])

一般来说,where()在大多数情况下都可以工作。

这里有一个很棒的帖子: https://web.archive.org/web/20150206131559/http://m.onkey.org/active-record-query-interface

编辑: 这个答案是非常古老和其他,更好的答案已经出来了,因为这个帖子。我建议你看看下面@Hossam Khamis 发布的帖子,了解更多细节。

选择你认为最适合你需要的。

find方法通常用于按 ID 检索行:

Model.find(1)

值得注意的是,如果提供的属性未找到该项,find将引发异常。使用 where(如下所述,如果找不到属性,它将返回一个空数组)以避免引发异常。

find的其他用途通常被这样的东西所取代:

Model.all
Model.first

当您在列中搜索信息时,find_by被用作助手,它映射到具有命名约定的列中。例如,如果在数据库中有一个名为 name的列,那么应该使用以下语法:

Model.find_by(name: "Bob")

.where更像是一个 catch all,它允许您在常规助手无法执行的情况下使用更复杂的逻辑,并且返回一个符合条件的项数组(否则返回一个空数组)。

findfind_by之间的区别在于,如果没有找到,find将返回错误,而 find_by将返回 null。

有时,如果你有一个像 find_by email: "haha"这样的方法,相对于 .where(email: some_params).first,读起来会更容易。

何处 返回 ActiveRecord: : 关系

现在来看一下 find _ by 的实现:

def find_by
where(*args).take
end

正如您所看到的,找到哪里相同,但它只返回一条记录。这种方法应用于获取1条记录,哪里应用于在一定条件下获取所有记录。

因为 Rails 4你可以做:

User.find_by(name: 'Bob')

相当于 Rails 3中的 find_by_name

#find#find_by不够时使用 #where

公认的答案基本涵盖了所有问题但我想补充一点, 如果你打算用更新这样的方式来处理模型,而你只检索一条记录(你不知道它的 id) ,那么 find_by就是最好的方法,因为它检索记录而不是把它放到数组中

irb(main):037:0> @kit = Kit.find_by(number: "3456")
Kit Load (0.9ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" =
'3456' LIMIT 1
=> #<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56",
updated_at: "2015-05-12 06:10:56", job_id: nil>


irb(main):038:0> @kit.update(job_id: 2)
(0.2ms)  BEGIN Kit Exists (0.4ms)  SELECT 1 AS one FROM "kits" WHERE
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.5ms)
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE  "kits"."id" =
1  [["job_id", 2], ["updated_at", Tue, 12 May 2015 07:16:58 UTC +00:00]]
(0.6ms)  COMMIT => true

但是如果你使用 where,那么你不能直接更新它

irb(main):039:0> @kit = Kit.where(number: "3456")
Kit Load (1.2ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" =
'3456' => #<ActiveRecord::Relation [#<Kit id: 1, number: "3456",
created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 07:16:58",
job_id: 2>]>


irb(main):040:0> @kit.update(job_id: 3)
ArgumentError: wrong number of arguments (1 for 2)

在这种情况下,您必须像这样指定它

irb(main):043:0> @kit[0].update(job_id: 3)
(0.2ms)  BEGIN Kit Exists (0.6ms)  SELECT 1 AS one FROM "kits" WHERE
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.6ms)
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1
[["job_id", 3], ["updated_at", Tue, 12 May 2015 07:28:04 UTC +00:00]]
(0.5ms)  COMMIT => true

除了接受的答案,以下也是有效的

Model.find()可以接受 id 数组,并返回所有匹配的记录。 Model.find_by_id(123)也接受数组,但只处理数组中的第一个 id 值

Model.find([1,2,3])
Model.find_by_id([1,2,3])

假设我有一个 User模型

  1. User.find(id)

返回一行,其中主键 = id。返回类型为 User对象。

  1. User.find_by(email:"abc@xyz.com")

在这种情况下,返回具有匹配属性或电子邮件的第一行。返回类型将再次为 User对象。

注意:-User.find_by(email: "abc@xyz.com")类似于 User.find_by_email("abc@xyz.com")

  1. User.where(project_id:1)

返回属性匹配的用户表中的所有用户。

这里的返回类型将是 ActiveRecord::Relation对象。ActiveRecord::Relation类包含 Ruby 的 Enumerable模块,因此您可以像使用数组一样使用它的对象并遍历它。

Model.find

参数: 要查找的对象的 ID。

2-If found: 它返回对象(只有一个对象)。

3-如果没有找到: 引发 ActiveRecord::RecordNotFound异常。

Model.find_by

参数: key/value

例如:

User.find_by name: 'John', email: 'john@doe.com'

2-If found: 它返回对象。

3-如果找不到: 返回 nil

注意: 如果你想提高 ActiveRecord::RecordNotFound,使用 find_by!

Model.where

1-参数: 与 find_by相同

2-If found: 它返回包含一条或多条与参数匹配的记录的 ActiveRecord::Relation

3-如果没有找到: 它返回一个空的 ActiveRecord::Relation

我个人建议使用

where(< columnname> => < columnvalue>)

到目前为止给出的答案都是可以的。

然而,一个有趣的区别是,Model.find通过 id 进行搜索; 如果找到,它返回一个 Model对象(只有一条记录) ,但是抛出一个 ActiveRecord::RecordNotFound

Model.find_by非常类似于 Model.find,允许您搜索数据库中的任何列或列组,但是如果没有记录与搜索匹配,它将返回 nil

另一方面,Model.where返回一个类似于包含 所有符合搜索条件的记录的数组的 Model::ActiveRecord_Relation对象。如果没有找到记录,则返回一个空的 Model::ActiveRecord_Relation对象。

我希望这些能帮助您在任何时候决定使用哪一个。

使用任何开源技术的最好部分是您可以检查它的长度和广度。 看看这个链接

Find _ by ~ > 查找匹配指定条件的第一条记录。没有隐含的顺序,所以如果顺序问题,你应该指定它自己。如果找不到记录,则返回空。

查找符合指定条件的第一条记录,但如果没有找到记录,它会引发异常,但这是有意为之。

做好上面的链接,它有以下两个功能的全部说明和用例。