非事务性地保存ActiveRecord

时间:2010-06-17 14:26:25

标签: ruby-on-rails activerecord transactions

我的应用程序接受文件上传,其中一些元数据存储在数据库中,文件本身存储在文件系统中。我试图在文件上传和后期处理完成之前使应用程序中的元数据可见,但由于保存是事务性的,我没有成功。我已经尝试了回调并调用create_or_update()而不是save(),但都无济于事。有没有办法在不重写ActiveRecord :: Base的内容的情况下做到这一点?我甚至尝试过命名方法make()而不是save(),但令人费解的是没有效果。

下面的代码“工作正常”,但是在完成所有其他操作之前不会修改数据库。

def save(upload)

uploadFile = upload['datafile']
originalName = uploadFile.original_filename
self.fileType = File.extname(originalName)

create_or_update()

# write the file
File.open(self.filePath, "wb") { |f| f.write(uploadFile.read) }
begin
  musicFile = TagLib::File.new(self.filePath())
  self.id3Title = musicFile.title
  self.id3Artist = musicFile.artist
  self.id3Length = musicFile.length
 rescue TagLib::BadFile => exc
    logger.error("Failed to id track: \n #{exc}")
end

if(self.fileType == '.mp3')
  convertToOGG();
end
create_or_update()

end

非常欢迎任何想法,谢谢。

2 个答案:

答案 0 :(得分:1)

您是否考虑过将文件上传作为后台任务处理?正常保存元数据,然后使用延迟作业或类似操作执行上载和后处理。 This Railscast有详细信息。

答案 1 :(得分:1)

你从文件中获取元数据,对吧?转换为OGG的问题花费的时间太长了,您希望数据在转换之前出现吗?

如果是这样,上面的John有正确的想法 - 您将需要接受文件上传,并安排在将来某个时间进行转换。

主要原因是您的rails线程将处理OGG转换,并且在完成之前无法响应任何其他Web请求。爆破!

有些服务器通过拥有多个铁路线程来弥补这一点,但我建议使用后台队列(如果您自己托管则使用BJ,如果您在那里托管,则使用Heroku的后台作业)。