【问题标题】:Extract and validate data from attachment从附件中提取和验证数据
【发布时间】:2015-02-19 21:15:48
【问题描述】:

我正在使用paperclip 来管理我在 Rails 中上传的文件。

从用户给我的附件中,我想提取一些数据与附件关联的模型相关联。

has_attached_file :resume, #...
# ...
def extract_resume_summary
  path_to_resume = self.resume.queued_for_write[:original].path
  extracted = parse_resume_file(path_to_resume)
  self.number_of_jobs = extracted.number_of_jobs
  self.highest_level_of_education = extracted.highest_level_of_education
rescue ResumeParseError => e
  @problem_with_resume = e.message
end

我无法准确地确定 何时何处 来执行此操作。

我可以使用自定义Paperclip::Processor

class ::Paperclip::Summary < ::Paperclip::Processor
  def make
    @attachment.instance.extract_resume_summary
    Tempfile.new('unused')
  end
end
# ...
has_attached_file :resume, 
                  :styles => { :summary => {} }, 
                  :processors => [ :summary ] }, #...

但是合身不是很好。我认为处理器旨在创建新文件(我不需要,因此是虚假的Tempfile)。

我的提取也可能失败,这意味着我的用户给了我错误的数据。我希望这是一个验证时问题,因此我可以将它与其他验证错误一起报告,并且后处理严格在验证之后进行。

我尝试在初始化时破解它:

validate :successfully_parses_resume

def successfully_parses_resume
  errors.add(:resume, @problem_with_resume) if @problem_with_resume
end

def initialize(attributes=nil, options={})
  super
  extract_resume_summary
end

但我也不太确定这是否正确,因为不仅在文件上传时如此,而且在我稍后读取模型时也是如此。如果我假设 #resume=#[:resume]= 也会自动更新提取的数据,更不用说可能发生的破坏了。

我认为在理想的世界中,我只需将Paperclip::Attachment 子类化,并使我提取的数据与resume_file_nameresume_file_sizeresume_content_typeresume_created_at 对等,同时提取mime-计算类型并计算文件大小。但看看源代码,这些都是相当硬编码的。

还有其他我忽略的方法吗?

【问题讨论】:

    标签: ruby-on-rails validation paperclip


    【解决方案1】:

    我想出的解决方案是包装附件的设置器。这就是initialize 期间将调用的内容,这将使我有机会在验证之前发现问题。

    唯一的技巧是,由于附件的 setter 是由has_attached_file 创建的,而不是从ActiveRecord::Base 继承的,所以我不能只使用super,我需要明确引用@987654325 定义的版本@(通过alias 或者,我的偏好,通过instance_method):

    has_attached_file :resume
    
    old_setter = instance_method :resume=
    define_method :resume= do |file|
      old_setter.bind(self).call(file)
      begin
        extracted = parse_resume_file(resume.path)
        self.number_of_jobs = extracted.number_of_jobs
        self.highest_level_of_education = extracted.highest_level_of_education
      rescue ResumeParseError => e
        @problem_with_resume = e.message
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-06
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 2014-08-20
      相关资源
      最近更新 更多