Подтвердить что ты не робот

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 только в том случае, если файл включен в представление формы... но я не уверен, как это сделать.

4b9b3361

Ответ 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" %>