我跟着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
模型?
答案 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
希望这是有道理的。继续 - 你会到达那里。