我是铁杆新手。我看到有很多方法可以找到记录:
find_by_<columnname>(<columnvalue>)
find(:first, :conditions => { <columnname> => <columnvalue> }
where(<columnname> => <columnvalue>).first
看起来所有这些都会产生完全相同的SQL。此外,我相信找到多个记录也是如此:
find_all_by_<columnname>(<columnvalue>)
find(:all, :conditions => { <columnname> => <columnvalue> }
where(<columnname> => <columnvalue>)
是否有经验法则或建议使用哪一个?
答案 0 :(得分:113)
其中返回ActiveRecord :: Relation
现在看一下find_by的实现:
def find_by
where(*args).take
end
正如您所看到的, find_by 与其中相同,但它只返回一条记录。此方法应该用于获取1条记录,其中应该用于获取具有某些条件的所有记录。
答案 1 :(得分:79)
使用您认为最适合自己需要的任何一种。
find
方法通常用于按ID检索行:
Model.find(1)
值得注意的是,如果您提供的属性找不到该项,find
将抛出异常。使用where
(如下所述,如果找不到该属性,将返回一个空数组)以避免抛出异常。
find
的其他用法通常会替换为以下内容:
Model.all
Model.first
当您在列中搜索信息时, find_by
用作帮助程序,并使用命名约定映射到此类。例如,如果数据库中有一个名为name
的列,则使用以下语法:
Model.find_by(name: "Bob")
.where
更像是一个捕获所有允许你使用更复杂的逻辑的传统助手不会做的事情,它返回一个符合你条件的项目数组(否则为空数组) )。
答案 2 :(得分:31)
find
和find_by
之间存在差异,find
如果找不到则会返回错误,而find_by
将返回null。
如果您使用find_by email: "haha"
方法,而不是.where(email: some_params).first
,则有时会更容易阅读。
答案 3 :(得分:29)
<强> Model.find
强>
1-参数:要查找的对象的ID。
2-如果找到:它返回对象(仅一个对象)。
3-如果未找到:引发ActiveRecord::RecordNotFound
例外。
<强> Model.find_by
强>
1-参数:键/值
示例:
User.find_by name: 'John', email: 'john@doe.com'
2-如果找到:它返回对象。
3-如果未找到:返回nil
。
注意: 如果您希望它引发ActiveRecord::RecordNotFound
使用find_by!
<强> Model.where
强>
1-参数:与find_by
2-如果找到:它返回ActiveRecord::Relation
,其中包含一个或多个与参数匹配的记录。
3-如果未找到:它返回空ActiveRecord::Relation
。
答案 4 :(得分:16)
从Rails 4开始,你可以这样做:
User.find_by(name: 'Bob')
这是Rails 3中的等效find_by_name
。
#where
和#find
不够时使用#find_by
。
答案 5 :(得分:9)
接受的答案通常涵盖了所有内容,但我想补充一些内容,
只是因为你计划以更新的方式使用模型,而你正在检索单个记录(你不知道的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
答案 6 :(得分:6)
您的列表中的两个#2都已被弃用。您仍然可以使用find(params[:id])
。
通常,where()
适用于大多数情况。
答案 7 :(得分:5)
除了已接受的答案,以下内容也有效
Model.find()
可以接受id数组,并返回匹配的所有记录。
Model.find_by_id(123)
也接受数组,但只会处理数组
Model.find([1,2,3])
Model.find_by_id([1,2,3])
答案 8 :(得分:2)
假设我有一个模型用户
User.find(id)
返回id指向的行。所以假设,如果id = 1,那么它将返回第一行。返回类型将是User对象。
User.find_by(email:"abc@xyz.com")
在这种情况下,返回具有匹配属性或电子邮件的第一行。返回类型将再次为User对象。
User.where(project_id:1)
返回属性匹配的users表中的所有用户。这里的返回类型将是包含User对象列表的ActiveRecord :: Relation对象。
答案 9 :(得分:1)
到目前为止给出的答案都还可以。
但是,一个有趣的区别是Model.find
通过id搜索;如果找到,它将返回一个Model
对象(仅一条记录),否则将抛出一个ActiveRecord::RecordNotFound
。
Model.find_by
与Model.find
非常相似,可让您搜索数据库中的任何列或一组列,但是如果没有记录与搜索匹配,它将返回nil
。
Model.where
返回一个Model::ActiveRecord_Relation
对象,该对象就像一个包含与搜索匹配的所有记录的数组。如果未找到任何记录,它将返回一个空的Model::ActiveRecord_Relation
对象。
希望这些可以帮助您决定在任何时间使用哪个。
答案 10 :(得分:0)
使用任何开源技术的最好的部分是您可以检查它的长度和宽度。 Checkout this link
find_by〜>查找符合指定条件的第一条记录。没有隐含的订购,因此,如果订购很重要,则应自己指定。如果未找到任何记录,则返回nil。
查找〜>查找符合指定条件的第一条记录,但是如果未找到任何记录,则将引发异常,但这是有意进行的。
请检查以上链接,其中包含以下两个功能的所有说明和用例。
答案 11 :(得分:-3)
我个人建议使用
where(< columnname> => < columnvalue>)