1

我正在创建一个带有文件信息的模型,但如果有这样的文件(通过文件哈希检查)我应该返回现有的文件模型。但我想知道在控制器中,它是不是新的。我想我可以返回包含现有模型的模型和布尔变量的数组,但它的解决方案很丑。

也许我应该移动部分是将文件上传到另一个模块或其他东西,但是在此过程中提取的数据几乎是所有模型字段,我不想从该模块返回它,然后检查现有文件模型并创建它如果它是新的。但也许这是正确的方法。

模型:

class SourceFileInfo
  include Mongoid::Document
  include Mongoid::Timestamps

  field :name, type: String
  field :ext, type: String
  field :path, type: String
  field :original_name, type: String
  field :hash, type: String

  validates_uniqueness_of :name, :hash
  validates_presence_of :name, :path

  belongs_to :user
  belongs_to :book_info

  def self.find_or_create_from_params file_params, user
    # collect file data - name, ext, path
    require 'securerandom'
    original_name = file_params.original_filename

    directory = Rails.root.join("upload")
    file_id = SecureRandom.hex
    ext = original_name.split('.').last

    fb2_file_name = "#{file_id}.#{ext}"

    file_path = File.join(directory, fb2_file_name)
    File.open(file_path, "wb") { |f| f.write(file_params.read) }

    # check file exists in db and return it if it does
    require 'digest/md5'
    hash = Digest::MD5.hexdigest(File.read file_path)
    return SourceFileInfo.where(hash: hash).first if SourceFileInfo.where(hash: hash).exists?

    # else return new model
    create(name: file_id, ext: ext, path: file_path,
           original_name: original_name, user: user)
  end
end

控制器:

  def upload_book
    file_info = SourceFileInfo.find_or_create_from_params(file_params[:file], current_user)

    BookFileWorker.perform_async file_info.id.to_s

    render nothing: true
  end

提前感谢您的回答。

4

1 回答 1

1

您不需要重写该find_or_create方法,因为它已经存在并且可以执行您想要的操作。

不要像现在这样在模型中生成哈希,为什么不在控制器中使用类似以下的东西:

def upload_book
    hash = Digest::MD5.hexdigest(File.read(file_path))
    file_info = SourceFileInfo.find_or_initialize(hash: hash)
    if file_info.new_record?
        ... fill in other info and save record
    else
        ... do whatever else
    end 
end

find_or_create_from_params然后可以通过删除该方法来清理您的模型。

于 2013-10-26T22:38:29.450 回答