回形针的动态内容类型验证

Dynamic content type validation for paperclip

这是我的 Rail4 应用程序:该应用程序将有很多服务,每个服务可能有很多提交。提交可以是图片,也可以是word文件,也可以是pdf文件。但是,提交的内容类型实际上是由服务对象定义的。

我知道有一个validates_attachment_content_type功能,但问题是如何根据服务对象动态更改content_type?

这是我的项目的代码:

class Service < ActiveRecord::Base
  attr_acccessor :service_content_type
  has_many :submissions
end

class Submission < ActiveRecord::Base
  belongs_to :service

  has_attached_file :attachment
  validates_attachment_content_type :attachment, 
    :content_type => self.service.service_content_type # THIS LINE IS NOT WORKING
end

self.service.service_content_type 必须是正则表达式,我猜不是。阅读 doc

一个问题是验证是在 class 上下文中声明的。 self 这里指的是 class,不是实例,所以调用 self.service 会引发错误,因为 service 是一个实例方法。

ActiveModel 验证通常让您传入一个 lambda 块,您可以在其中使用实例来确定有效性。但是 Paperclip doc 表示 validates_attachment_content_type 只允许您传入包含这两种类型元素的字符串、正则表达式或数组。

您可以使用自定义验证方法来确保您的 attachment_content_type 列是正确的值。但我不能 100% 确定这是否提供与 validates_attachment_content_type.

相同的安全性
class Submission < ActiveRecord::Base
  belongs_to :service

  has_attached_file :attachment

  validate :validate_content_type

  def validate_content_type
    unless attachment_content_type == service.service_content_type
      errors.add(:attachment_content_type, "must be #{service.service_content_type}")
    end
  end
end

或者您可以使用带有 lambda 的内置 Rails 验证,但对错误消息的控制较少:

  validates :attachment_content_type,
    inclusion: { in: ->(submission) { [submission.service.service_content_type] } }

您可以通过以下方式访问:

validates_attachment_content_type :attachment, :content_type => @service.service_content_type

它在以下上下文中对我有用(这是一个数组而不是 "object",但我想它应该翻译):

validates_attachment_content_type :detail, :content_type => @IMAGE_VIDEO_AUDIO_FILE_CONTENT_TYPES