我正在创建一个包含文件信息的模型,但如果有这样的文件(通过文件哈希检查),我应该返回现有的文件模型。但我想在控制器中知道,是否新的。我想我可以返回包含现有模型的模型和布尔变量的数组,但它的丑陋解决方案。
也许我应该移动部分是将文件上传到另一个模块或者什么,但是在这个过程中提取的数据几乎都是模型字段,我不想从该模块返回它,然后检查现有文件模型并且如果它是新的则创建它。但也许这是正确的方法。
型号:
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
提前感谢您的回答。
答案 0 :(得分: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
方法可以清理您的模型。