Как проверить, отправляется ли новый файл с Active Storage в модели? - PullRequest
0 голосов
/ 05 декабря 2018

В моей модели Rails у меня есть этот код для принудительного изменения имени файла при загрузке:

before_save :set_filename  
  def set_filename
    if file.attached?
      self.file.blob.update(filename: "#{new_file_name()}.#{self.file.blob.content_type.split('/')[1]}")
    end
  end

Проблема в том, что имя файла изменяется, даже если новый файл не отправляется в форме (при редактировании).

Мое вложение называется просто файл:

# active storage
  has_one_attached :file

Как действительно проверить, что новый файл прилагается при загрузке?

Спасибо,

РЕДАКТИРОВАТЬ: больше уточнений

У меня есть форма с полем file_.Я хочу проверить, отправляется ли новый файл через форму, когда я добавляю или изменяю объект формы.

Моя модель называется Image, а прикрепленный файл называется file.

class Image
  has_one_attached :file
end

Я хочу менять имя файла каждый раз, когда через форму отправляется новый файл, и, разумеется, поле file_field остается пустым.

1 Ответ

0 голосов
/ 05 декабря 2018

Вы можете использовать new_record? , чтобы проверить, является ли file новым, то есть:

  def set_filename
    if file.attached? && file.new_record?
      self.file.blob.update(filename: "#{new_file_name()}.#{self.file.blob.content_type.split('/')[1]}")
    end
  end

В качестве альтернативы, используйте before_create вместо before_save, чтобы только set_nameзапускается при загрузке нового файла.

Обновлено

Интересно, что ActiveStorage обрабатывает изменения больших двоичных объектов вне хуков модели.По-видимому, сейчас он даже не поддерживает проверку.Нет никакого способа проверить, что блоб изменился, поскольку его состояние нигде не сохраняется.Если вы загляните в журнал rails, обратите внимание, что rails удаляет старый BLOB-объект, как только добавляется новый.

Несколько вариантов, которые я могу вспомнить:

1. Обновление имени файла в контроллере, например:

original_name = params[:file].original_name
params[:file].original_name = # your logic goes here

2. Сохраните имя файла BLOB-объекта в родительской модели и сравните в before_save.

  def set_filename
    if file.attached? && file.blob.filename != self.old_filename
      self.file.blob.update(filename: "#{new_file_name()}.#{self.file.blob.content_type.split('/')[1]}")
    end
  end

Ни одно из этих решений не является идеальным, но надеюсь, что оно даст вам некоторые идеи.

...