【发布时间】:2017-02-11 17:05:53
【问题描述】:
first_or_create 似乎记录得少得多,所以我想知道这是否只是因为这两种方法是同义词。
【问题讨论】:
标签: ruby-on-rails activerecord
first_or_create 似乎记录得少得多,所以我想知道这是否只是因为这两种方法是同义词。
【问题讨论】:
标签: ruby-on-rails activerecord
基本上:
Foo.where(attributes).first_or_create
等同于:
Foo.find_or_create_by(attributes)
#first_or_create 有时会被误解为人们期望它根据给定的属性进行搜索,但事实并非如此。阿卡
Foo.first_or_create(attributes)
不会搜索满足attributes 的foo。如果有的话,它将采用第一个foo。如果查找条件是用于创建的条件的子集,这将很有用。阿卡
Foo.where(something: value).first_or_create(attributes)
将在something: value 处找到第一个foo。如果不存在,它将使用attributes 创建它。
【讨论】:
first_or_create 将使用ORDER BY id LIMIT 1,而find_or_create_by 将仅使用LIMIT 1。在大多数情况下这无关紧要,但随着数据集的增长,您可能会发现这种微小的差异会使事情变慢几个数量级(即使有索引)。
find_or_*_by 应该是where(..).first_or_* 的首选语法
first_or_create 出现在 Rails 3.2.19 中,并且在 Rails 4.0 中被弃用了。在那段时间里,它的代码没有太大变化。这一切都归结为first,它按id 排序,除非明确指定其他排序。
first_or_create 是否曾取消过 ORDER BY 子句。
@ndnenkov 的回答是对的,但我想详细说明为什么我认为有人可能会使用 find_or_create:
考虑 Foo 必须具有 attribute_subset_1 或 attribute_subset_2 才能创建它的情况。可以(伪)将其编码为:
if attribute_subset_1 then
Foo.where(attribute_subset_1).first_or_create(attributes)
elsif attribute_subset_2 then
Foo.where(attribute_subset_2).first_or_create(attributes)
else
Raise error " insufficient attributes"
end
这是我认为find_or_create_by 不起作用的情况......至少不容易。我很想知道是否有任何不同的看法,但对我来说,我发现first_or_create 的这种用法非常适合我的需求。
【讨论】: