我有一个模型,比如说附件,它使用 attachment_fu 来接受用户上传的文件。我想“深度复制”(或在 Ruby-ese 中,深度克隆)一个附件,从而在“db_files”表中创建一个全新的二进制对象。
我发现这还不是一个完全解决的问题。这篇博文:http: //www.williambharding.com/blog/rails/rails-faster-clonecopy-of-attachment_fu-images/
展示了一种据称适用于基于文件系统的存储的方法。对于基于数据库的存储,“深拷贝”失败。创建了一个新的“附件”,但它使用了预先存在的 db_file_id,因此执行了浅拷贝。
在 attachment_fu 的 db_file_backend.rb 中,我看到了保存方法:
# Saves the data to the DbFile model
def save_to_storage
if save_attachment?
(db_file || build_db_file).data = temp_data
db_file.save!
self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
end
true
end
所以,我试图破译这一点,我相信“build_db_file”是 DbFile.new 的一些 Ruby 元编程魔术速记,尽管我无法确认这一点(grepping 源显示没有提及这一点,我也无法在谷歌上找到它)。
我不太确定它在做什么,但我的理论是,作为“深拷贝”尝试的一部分(在链接代码中),正在从源 obj 复制 db_file,因此它只是触发保存而不是创造。
我最初的理论是父(附件)对象将在深拷贝尝试时设置为“新”,因此我做了类似的事情:
def save_to_storage
if save_attachment?
if self.new_record?
db_file = DbFile.new :data => temp_data
self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
end
end
true
end
这实际上适用于克隆对象,但不幸的是,所有常规、非克隆文件上传的测试都失败了。附件对象已创建,但没有数据写入 db_file。理论上是先保存父对象,然后再写入db_file的东西,因此new_record?返回假。
所以,作为一个实验,我决定尝试:
def save_to_storage
if save_attachment?
if self.new_record?
db_file = DbFile.new :data => temp_data
self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
else
(db_file || build_db_file).data = temp_data
db_file.save!
self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
#end
end
true
end
这部分有效 - db_file 已填充,但随后我在 db_file.save 上收到错误!- 说 db_file 为零。
所以,我有点受阻。我可以做一些进一步的试验和错误,但在这一点上,我对这个插件如何工作的理解有限。我真的没想到也不想花这么多时间在上面,所以我不愿意进一步探索attachment_fu,但恐怕我将不得不深入兔子洞才能弄清楚。有什么想法或想法吗?
谢谢!!