我有一个模型,让我们说Attachments,它使用attachment_fu来接受用户的文件上传。我想“深层复制”(或在Ruby-ese中深层克隆)Attachment,从而在“db_files”表中创建一个全新的二进制对象。Rails,Attachment_fu - 数据库存储附件的深层副本
我发现它还没有完全解决问题。此博客文章: 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”是一些Ruby的元编程魔法速记DbFile.new虽然我不能确认这(grepping的来源显示没有提到这一点,我也不能在谷歌上找到它)。
我不太清楚它在做什么,但我的理论是,db_file是从源obj复制的,作为“深度复制”尝试(在链接代码中)的一部分,因此它只是触发一个保存而不是创建。
我最初的理论是,父(见附件),对象将在深拷贝尝试设置为“新的”,因此,我不喜欢的东西:
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?返回false。
因此,作为一个实验,我决定尝试:
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,但恐怕我不得不去掉兔子洞来弄清楚。任何想法或想法?
谢谢!
注意:更优雅的解决方案是使用引用计数形式,并使所有Attachment obj指向相同的db_file_id。只有在没有附件指向它时删除db_file。嗯 – 2010-02-05 19:36:25