Ruby 模型查找或创建架构



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

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

型:

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

提前感谢您的回答。

您不需要重写 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 方法清理模型。

最新更新