Rails: Как мне запустить before_save, только если соблюдены определенные условия? - PullRequest
12 голосов
/ 28 апреля 2010

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

Ответы [ 4 ]

12 голосов
/ 28 апреля 2010

Использовать грязные объекты .

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
4 голосов
/ 07 октября 2012
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% времени

1 голос
/ 28 апреля 2010

сделайте так, чтобы ваш метод before_save вызывался при каждом сохранении, но в качестве первого шага в методе, который вы теперь вызываете, «перед сохранением», вы должны иметь условие if, которое проверяет конкретный нужный вам случай.

0 голосов
/ 28 апреля 2010

Просто сделайте быструю проверку в верхней части функции и вернитесь, если вам ничего не нужно делать.

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" %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...