#ruby-on-rails #activerecord
#ruby-on-rails #активный файл
Вопрос:
Если я сделаю
widget = Widget.find_or_create_by_widgetid(:widgetid => "12345", :param2 => "folk")
и т.д. Тогда как мне определить, является ли newobj найденным или только что созданным виджетом? Есть ли что-нибудь, что я могу протестировать условно widget
, что подскажет мне?
Комментарии:
1. Вы могли бы проверить
created_at
атрибут и сравнить его сTime.now
, чтобы тоже получить какое-то представление.
Ответ №1:
Я не верю, что есть способ определить, создан ли объект недавно или уже был там. Вместо этого вы могли бы использовать 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
Комментарии:
1. Я начал рассматривать возможность сделать это таким образом, спасибо, что подтвердили это как жизнеспособный вариант.
2. В зависимости от того, чего вы хотите достичь, вы также можете использовать
find_or_initialize_by_widgetid
с блоком. Блок будет выполнен только для вновь инициализированной записи.3.
find_or_create_by_
также принимает блок, который будет переданcreate
и, таким образом, запускаться только при создании новой записи.
Ответ №2:
Rails 4
find_or_create_by (атрибуты и блок)
Теперь этот метод принимает блок, который передается в create, поэтому я бы выбрал:
widget = Widget.find_or_create_by(:widgetid => "12345", :param2 => "folk") do |w|
# if you got in here, this is a new widget
end
Другим способом сделать это в Rails 4 было бы:
widget = Widget.where(:widgetid => "12345", :param2 => "folk").first_or_initialize
if widget.new_record?
# this is a new widget
end
Ответ №3:
В зависимости от того, что вы хотите сделать, вы можете использовать блок:
widget = find_or_create_by(widgetid: "12345") do |widget|
widget.param2 = "folk"
if widget.new_record?
# Code for a new widget.
else
# Code for an existing widget.
end
end
Комментарии:
1. На самом деле, как указано в artm выше (и в документации указано), блок передается только в ‘create’, поэтому нет необходимости проверять наличие нового.