如何测试模型中是否使用Active Storage发送了新文件?

时间:2018-12-05 19:42:57

标签: ruby-on-rails rails-activestorage

在我的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_field的表格。 添加或修改表单对象时,我想测试是否通过表单发送了新文件。

我的模型称为Image,附加文件称为file。

class Image
  has_one_attached :file
end

每次通过表单发送新文件时,我都想更改文件名,当然file_field不会为空。

1 个答案:

答案 0 :(得分:2)

您可以使用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处理模型挂钩之外的Blob变化。显然,它现在甚至不支持验证。由于无法在任何地方持久保存其状态,因此无法验证blob是否已更改。如果您查看Rails日志,请注意,一旦添加了新的Blob,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

这些解决方案都不是理想的,但希望它们能给您一些想法。