first_or_create仅插入

时间:2018-07-20 05:38:00

标签: ruby-on-rails ruby if-statement

我在Rails 5.2项目中使用以下代码:

c = Country.where(name: "test").first_or_create

c.status = "Old"
c.save

这有效,但是,我只想在没有国家/地区的情况下更改状态(所以我只想插入国家/地区,而不要更新)。但是,稍后我还需要在代码中使用c

我意识到我可以做一个if语句,但是我必须在代码中多次做类似的事情,而且似乎必须存在一个快捷方式。

3 个答案:

答案 0 :(得分:4)

通过以下方式使用create_with

c = Country.create_with(status: 'old').find_or_create_by(name: 'test')

这只会使用Country 'old'status 'test'创建name,并且只有在不这样做的情况下”找不到名称为'test'的国家/地区。如果确实找到名称为'test'的国家/地区,则不会更新状态。

最终,无论找到还是创建,它都会在c中返回该国家/地区。

create_with仅在从关系对象创建新记录时设置属性。

答案 1 :(得分:0)

默认情况下,where返回数组类型,您将需要迭代以分配新值。

然后find_by返回实际对象或nil。

Country.where(name: "nothing") => [] or [obj, ...]
Country.find_by(name: "nothing") => nil or object

您可以使用find_or_create选项:

Country.find_or_create_by(name: 'test') do |c|
  c.status = "Old"
end


c = Country.find_or_create_by(name: 'test')
c.status = "Old"
c.save

答案 2 :(得分:0)

first_or_create方法在表中查找结果,如果表中存在结果,则将返回第一个实例。如果不是,则调用create。

如果提供了一个块,则仅在创建新实例时才执行该块。该块不会在现有记录上执行。

因此,如果您只想在创建国家/地区时更改状态,则将first_or_create方法与block一起使用。

所以您的代码看起来像

Country.where(name: "test").first_or_create do |country|
  country.status = "Old"
  country.save
end