Rails ActiveRecord:如何找到或创建find_or_create_by?

Dav*_*ave 45 activerecord ruby-on-rails

可能是愚蠢的问题,但我只是没有得到它.

如果我做

widget = Widget.find_or_create_by_widgetid(:widgetid => "12345", :param2 => "folk") 
Run Code Online (Sandbox Code Playgroud)

那么如何判断newobj是找到的还是新创建的Widget?有什么东西我可以在小部件上有条件地测试会告诉我吗?

Sha*_*ell 56

我不相信有一种方法可以判断对象是新创建的还是已经存在.您可以使用find_or_initialize_by_widgetid而不保存新对象.然后widget.new_record?,您可以检查哪个会告诉您对象是否已保存.您必须在新对象的代码块中放置一个保存调用,但是无论如何都要进行检查,它不应该破坏代码流.

所以:

widget = find_or_initialize_by_widgetid(:widgetid => "12345", :param2 => "folk")
if widget.new_record?
  widget.save!
  # Code for a new widget
else
  # Code for an existing widget
end
Run Code Online (Sandbox Code Playgroud)

  • `find_or_create_by_`也接受一个块,它将被传递给`create`,因此只有在创建新记录时才会运行. (29认同)
  • 根据您想要实现的目标,您还可以将"find_or_initialize_by_widgetid"与块一起使用.该块仅对新初始化的记录执行. (2认同)

Fla*_*che 17

Rails 4

find_or_create_by(attributes,&block)

现在这个方法接受一个块,传递给创建,所以我选择:

widget = Widget.find_or_create_by(:widgetid => "12345", :param2 => "folk") do |w|
  # if you got in here, this is a new widget
end
Run Code Online (Sandbox Code Playgroud)

在Rails 4中执行此操作的另一种方法是:

widget = Widget.where(:widgetid => "12345", :param2 => "folk").first_or_initialize

if widget.new_record?
  # this is a new widget
end
Run Code Online (Sandbox Code Playgroud)