1

假设我们有一个处理创建、阅读、更新和删除文章的 Web 应用程序,并且每篇文章都应该有图片库。我必须在文章和画廊之间建立一对一的关系,在画廊和媒体之间建立一对多的关系。

HTML5 提供了很多功能,例如多重上传,所以我想为此使用这个出色的http://blueimp.github.io/jQuery-File-Upload/插件。问题是如何像其他表单的数据一样处理“内存中”的文件上传?

例如,当我们显示创建新文章的页面时,我们应该能够填写文章的数据字段并选择要上传的图像,接下来当我们单击保存按钮时,图像应该开始上传,然后表单应该提交。当验证失败时,图像仍应显示在前端,但应保存在服务器端 nothink 上。

解决方案之一是在显示整个表单之前创建类似于“创建实体会话临时 ID”的想法,并且该 ID 可用于创建临时目录以保存上传,因此在成功保存表单后,这些图像可以移动到适当的目录,但是如何制作“创建实体会话临时ID”?

我认为的另一个解决方案是“使用编辑 id”方法,因为我们可以使用以前保存的画廊 id 处理上传,但有时我无法用画廊保存新的空白文章,因为某些字段不应该为空在分贝。

对于 Rails,我在自述文件中看到https://github.com/thoughtbot/paperclip gem 说:

Paperclip 旨在作为 Active Record 的简单文件附件库。它背后的目的是使设置尽可能简单,并尽可能像对待其他属性一样对待文件。这意味着它们不会保存到磁盘上的最终位置,如果设置为 nil,它们也不会被删除,直到调用 ActiveRecord::Base#save。

我的问题是它是如何工作的?

4

2 回答 2

5

在创建掩码上启用文件上传的问题是您最终会得到孤立文件。这是因为用户能够在不保存实际实体的情况下触发上传。在创建一个非常自己的 UploadBundle 时,我考虑了这个问题一段时间,得出的结论是没有真正合适的解决方案。

我最终像这样实现它:

鉴于我们的问题是由孤立文件引起的,我创建了一个Orphanage负责管理这些文件的文件。上传的文件将首先与 session_id 一起存储在单独的目录中。这有助于区分不同用户的文件。提交表单以创建实际实体后,您可以仅使用会话 ID 从孤儿院检索文件。如果表单有效,您可以将文件从临时孤儿院目录移动到文件的最终目的地。

这种方法有一些缺陷:

  • 孤儿院目录本身应该使用 cron 作业等定期清理。
  • 如果用户将上传文件并选择不提交表单,而是从新表单重新开始,则新上传的文件将被移动到同一目录中。因此,您将获得第一次和第二次上传的文件后上传的文件。

这不是这个问题的最终解决方案,而是更多的解决方法。但在我看来,它比使用临时实体或基于会话的存储系统更干净。

提到的包在 Github 上可用,并且支持插件OrphanagejQuery File Uploader插件。

1up-lab/OneuploaderBundle

于 2013-08-09T14:41:06.330 回答
0

我没有亲自处理过这个案子,但我的同事也有类似的难题。她用

punkave/symfony2-file-uploader-bundle

这是一个包装 jQuery File Upload 插件的包。它处于早期阶段,缺少很多东西,例如事件,但我们试了一下。

这就是我们所做的:在 newAction() 中,我们创建实体,生成唯一的 dir ID,并将 ID 存储在实体中(通过常规 setDirId())。比我们创建包含隐藏字段 dirId 的表单。

我们正在通过 ajax 将文件上传到服务器上的临时目录,而不是在提交期间。Ajax 请求需要 ID。它将文件存储在 temp_dir/prefix_ID

比这很简单。表格已发送。如果表单有效 - 将文件从 temp 移动到 dest 目录。如果没有 - 我们有 ID,并且能够显示图像。

但是,我们不会将有关单个文件的信息保存在数据库中的单独表中。每次我们读取与我们的 dirId 对应的文件夹的内容。

我知道这不是您要求的解决方案。这是一种解决方法。

于 2013-08-09T13:40:35.647 回答