找vs vs find_by vs其中
我是新来的铁轨。 我看到有很多方法可以findlogging:
find_by_<columnname>(<columnvalue>)
-
find(:first, :conditions => { <columnname> => <columnvalue> }
-
where(<columnname> => <columnvalue>).first
而且它们看起来像是最终生成完全相同的SQL。 另外,我相信查找多个logging也是一样的:
-
find_all_by_<columnname>(<columnvalue>)
-
find(:all, :conditions => { <columnname> => <columnvalue> }
-
where(<columnname> => <columnvalue>)
有一个经验法则或推荐使用哪一个?
使用你觉得最适合你的需求。
find
方法通常用于通过ID检索行:
Model.find(1)
find
其他用途通常被replace为这样的东西:
Model.all Model.first
在search列中的信息时, Find_by
被用作帮助程序,并将其映射到命名约定。 例如,如果你的数据库中有一个名为name
的列,你可以使用下面的语法:
Model.find_by_name("Bob")
不过,我相信find_by
已被弃用。
所有这一切都可以让你使用一些更复杂的逻辑来处理传统帮手不会做的事情。
返回ActiveRecord :: Relation
现在看看find_by实现:
def find_by where(*args).take end
正如你所看到的, find_by与where相同,但是它只返回一条logging。 这个方法应该用于获取1条logging,并且在某些情况下应该用于获取所有logging。
find
和find_by
之间有一个区别,如果find
就会返回一个错误,而find_by
将返回null。
有时如果你有像find_by email: "haha"
那样的方法,比较容易阅读find_by email: "haha"
,而不是.where(email: some_params).first
。
由于Rails 4你可以这样做:
User.find_by(name: 'Bob')
这在Rails 3中是相当于find_by_name
。
当#find
和#find_by
不够时,使用#where
。
被接受的答案通常涵盖了所有的内容,但是我想补充一些东西,只是因为你打算用更新的方式来使用模型,而你正在检索一个单一的logging(你的id
不知道),那么find_by
是要走的路,因为它检索logging并不把它放在一个数组中
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
1-参数:要查找的对象的ID。
2-如果find:它返回对象(仅一个对象)。
3-如果找不到:引发ActiveRecord::RecordNotFound
exception。
Model.find_by
1-参数:键/值
例:
User.find_by name: 'John', email: 'john@doe.com'
2-如果find:它返回对象。
3-如果没有find:返回nil
。
注意:如果你想让它提高ActiveRecord::RecordNotFound
使用find_by!
Model.where
1-参数:与find_by
相同
2-如果find:它返回包含一个或多个匹配参数的logging的ActiveRecord::Relation
。
3-如果没有find:它返回一个空的ActiveRecord::Relation
。
列表中的#2都被弃用。 你仍然可以使用find(params[:id])
。
一般来说, where()
在大多数情况下都适用。
这里有一个很好的post: http : //m.onkey.org/active-record-query-interface
除了被接受的答案之外,以下也是有效的
Model.find()
可以接受ID数组,并将返回匹配的所有logging。 Model.find_by_id(123)
也接受数组,但只会处理数组中存在的第一个id值
Model.find([1,2,3]) Model.find_by_id([1,2,3])
假设我有一个模型用户
-
User.find(id)
返回由id指向的行。 所以假设,如果id = 1,那么它将返回第一行。 返回types将是User对象。
-
User.find_by(email:"abc@xyz.com")
在这种情况下返回具有匹配属性或电子邮件的第一行。 返回types将是User对象。
-
User.where(project_id:1)
返回属性匹配的用户表中的所有用户。 这里的返回types将是User对象的数组。
我会亲自推荐使用
where(< columnname> => < columnvalue>)