Rails 3和Paperclip问题 - 如何将上传的文件保存到文件系统?

时间:2011-06-22 00:20:25

标签: ruby-on-rails ruby-on-rails-3 file-upload paperclip multifile-uploader

我跟着this tutorial尝试将Paperclip集成到我的Rails 3应用程序中。

但是,我的案例与本教程中描述的内容略有不同。

就我而言,数据库中已存在User个模型,我想上传文件并将其与上传者关联。

以下是我的代码的相关部分:

class User < ActiveRecord::Base
  has_many :assets, :foreign_key => "uploader_id"
end

class Asset < ActiveRecord::Base
  belongs_to :uploader, :class_name => "User"  
  has_attached_file :asset, :styles => { :thumb => "100x100#" }
end

我的案例与教程之间的主要区别在于上传输入字段不在User的格式内:

# views/lounge/index.html.erb
<%= form_tag('/lounge/upload', :multipart => true) do %>
  <input id="uploader_id" name="uploader_id" type="hidden" />
  <%= file_field_tag "assets[]", :multiple => true %>
<% end %>

隐藏uploader_id输入字段的值由Javascript控制。

提交表单时,会调用upload方法:

class LoungeController < ApplicationController
  def upload
    uploader = User.find(params[:uploader_id])
    # ??
  end
end

我应该如何处理params[:assets]以将上传的文件保存到文件系统并在数据库中创建相应的Asset模型?

1 个答案:

答案 0 :(得分:1)

要保存文件,您需要创建资产模型,并将attached_file分配给那些模型(您也称为asset,这可能会让人感到困惑)。在简单的情况下,这看起来像:

user = User.find(id)
asset = user.assets.new
asset.asset = params[:asset]
asset.save

要做多个文件,只需快速循环:

user = User.find(id)
params[:assets].each do |asset|
  asset = user.assets.new
  asset.asset = asset
  asset.save
end

然而,你在这里做了很多非标准的事情,让你自己的生活更加艰难。不应使用file_field_tag,而应使用file_field帮助程序,并在内存中实例化Asset。例如,如果您按照链接的教程进行操作,那么您将拥有以下内容:

<% form_for @user do |f|
  <% f.fields_for :assets do |asset| %>
    <%= asset.file_field :asset %>
  <% end %>
<% end %>

您还需要告诉您的用户模型在保存时可以接受子资产模型:

def User
  accepts_nested_attributes_for :assets
end

然后在你的控制器动作中,你只需在内存中构建一些新资产,以便fields_for中的循环起作用:

def upload
  @user = User.find(id)
  5.times do { @user.assets.build }
end

希望这是有道理的。继续 - 你会到达那里。