Rails: Как запустить before_save только в случае выполнения определенных условий?
У меня есть метод before_save, который я вызываю, который переименовывает загруженное изображение.
before_save :randomize_file_name
def randomize_file_name
extension = File.extname(screen_file_name).downcase
key = ActiveSupport::SecureRandom.hex(8)
self.screen.instance_write(:file_name, "#{key}#{extension}")
end
Этот метод является частью моей модели Item
.
Это отлично работает, когда я создаю новый элемент или вам нужно обновить изображение, связанное с элементом... но проблема в том, что если мне нужно обновить элемент, но НЕ изображение, метод randomize_file_name
по-прежнему запускается и переименовывает файл в базе данных (хотя не сам файл, очевидно).
Итак, я думаю, мне нужно выяснить способ запускать randomize_file_name
только в том случае, если файл включен в представление формы... но я не уверен, как это сделать.
Ответы
Ответ 1
Используйте грязные объекты.
before_save :randomize_file_name
def randomize_file_name
# assuming the field that holds the name
# is called screen_file_name
if screen_file_name_changed?
extension = File.extname(screen_file_name).downcase
key = ActiveSupport::SecureRandom.hex(8)
self.screen.instance_write(:file_name, "#{key}#{extension}")
end
end
Ответ 2
before_save :randomize_file_name
def randomize_file_name
if screen_file_name
extension = File.extname(screen_file_name).downcase
key = ActiveSupport::SecureRandom.hex(8)
return self.screen.instance_write(:file_name, "#{key}#{extension}") unless !screen_changed?
end
end
Это проверяется только при изменении файла. Работает в 90% случаев
Ответ 3
и сделайте свой метод before_save указанным для каждого сохранения, но в качестве первого шага внутри метода, который вы сейчас вызываете "перед сохранением", у вас должно быть условие if, которое проверяет конкретный случай, который вам нужен.
Ответ 4
Просто выполните быструю проверку в верхней части функции и верните, если вам не нужно ничего делать.
def randomize_file_name
return unless screen_file_name # or whatever check you need to do
extension = File.extname(screen_file_name).downcase
key = ActiveSupport::SecureRandom.hex(8)
self.screen.instance_write(:file_name, "#{key}#{extension}")
end
Изменить после комментария:
Вы можете использовать грязный объект, как упомянуто Симоне Карлетти, или вы можете стать творческим.
В модели:
attr_accessor :some_random_field_name_for_you_to_rename
def randomize_file_name
return unless some_random_field_name_for_you_to_rename
extension = File.extname(screen_file_name).downcase
key = ActiveSupport::SecureRandom.hex(8)
self.screen.instance_write(:file_name, "#{key}#{extension}")
end
В форме:
<%= f.hidden_field :some_random_field_name_for_you_to_rename, :value => "1" %>