带有回形针的 Rails 4 多个文件附件 [英] Rails 4 multiple file attachments with Paperclip
问题描述
我知道有几篇关于 Stackoverflow 的帖子和几个关于这个主题的教程.然而,它们都没有解决我的问题,而且它们中的大多数也已经过时了.
I'm aware that there are several posts on Stackoverflow and several tutorials about this subject. None of them however manage to solve my issue and most of them are outdated as well.
我正在尝试使用 Rails 4 中的回形针 gem 将多个图像添加到项目中.当我尝试上传它时,我确实看到了参数中附加的资产.
I am trying to add multiple images to a project using the paperclip gem in Rails 4. When i try uploading it i do see the asset attached in the params.
它们似乎没有被添加到 project_paramns 中..
They do not seem to be added to the project_paramns though..
希望有人能帮助我.
这是我的projects_controller
class ProjectsController < ApplicationController
before_filter :find_project, only: [:show, :edit, :update, :destroy]
def index
@projects = Project.all
end
def show
end
def new
@project = Project.new
end
def create
@project = Project.new(project_params)
@project.save
redirect_to project_path(@project)
end
def edit
end
def update
@project.update(project_params)
redirect_to project_path(@project)
end
def destroy
@project.destroy
redirect_to projects_path
end
protected
def project_params
params.require(:project).permit(:name, :description, :asset)
end
def find_project
@project = Project.find(params[:id])
end
end
我的项目模型
class Project < ActiveRecord::Base
has_many :assets, :dependent => :destroy
validates_associated :assets
validates_presence_of :name, :on => :create, :update => "can't be blank"
validates_presence_of :description, :on => :create, :update => "can't be blank"
accepts_nested_attributes_for :assets
end
我的资产模型
class Asset < ActiveRecord::Base
belongs_to :project
# Paperclip
has_attached_file :image,
:styles => {
:thumb=> "100x100#",
:small => "150x150>",
:medium => "300x300>",
:large => "400x400>" }
validates_attachment :image, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] }
end
我的表单是部分的(抱歉是 HAML)
= simple_form_for @project do |f|
%ul
- @project.errors.full_messages.each do |error|
%li= error
.row
.small-1.columns
= f.label :name, :class => "left inline"
.small-11.columns
= f.input_field :name
.row
.small-1.columns
= f.label :description, :class => "left inline"
.small-11.columns
= f.input_field :description, as: :text
.row
= f.simple_fields_for :asset do |a|
.small-1.columns
= a.label :image, :class => "left inline"
.small-11.columns
= file_field_tag :image, multiple: true,
.row
.small-9.small-offset-1.columns
= f.submit nil ,:class => "button [radius round]"
请求参数
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"4iK1kUNvKvoJVOKoivz/pcLAe6LY0cUJikQioxa8BIs=", "project"=>{"name"=>"adf", "description"=>"adf", "asset"=>{"image"=>[#<ActionDispatch::Http::UploadedFile:0x007fb808357d80 @tempfile=#<Tempfile:/var/folders/v_/98sxm8bn24qbqj_jmj40fv400000gn/T/RackMultipart20140607-34739-dvlzt7>, @original_filename="enabling-gzip-compression.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name="project[asset][image][]"; filename="enabling-gzip-compression.jpg"
Content-Type: image/jpeg
">, #<ActionDispatch::Http::UploadedFile:0x007fb808357d58 @tempfile=#<Tempfile:/var/folders/v_/98sxm8bn24qbqj_jmj40fv400000gn/T/RackMultipart20140607-34739-lwkioi>, @original_filename="minimize_http_requests.png", @content_type="image/png", @headers="Content-Disposition: form-data; name="project[asset][image][]"; filename="minimize_http_requests.png"
Content-Type: image/png
">]}}, "commit"=>"Update Project", "action"=>"update", "controller"=>"projects", "id"=>"11"}
现在我的终端中也出现了一个错误:
Unpermitted parameters: asset
@pavan 和 @kiri thorat 的答案的组合帮助我在 project_params 中显示了一些东西,它现在给出的输出是:
A combination of @pavan's and @kiri thorat's answers have helped me get something showing up in project_params, the output it gives now is:
{"name"=>"Test", "description"=>"Test", "assets_attributes"=>{"0"=>{}}}
知道这里发生了什么吗?
Any clue on what's going on here?
在@kirithorat 的最新更新之后,参数方面的情况似乎很好.
After @kirithorat's latest update things seem to be good on the parameter side of things.
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"4iK1kUNvKvoJVOKoivz/pcLAe6LY0cUJikQioxa8BIs=", "project"=>{"name"=>"Test", "description"=>"Test", "assets_attributes"=>{"0"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007fcd383c9a08 @tempfile=#<Tempfile:/var/folders/v_/98sxm8bn24qbqj_jmj40fv400000gn/T/RackMultipart20140610-36517-7ek1oq>, @original_filename="enabling-gzip-compression.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name="project[assets_attributes][0][image]"; filename="enabling-gzip-compression.jpg"
Content-Type: image/jpeg
">}}}, "commit"=>"Update Project", "action"=>"update", "controller"=>"projects", "id"=>"13"}
资产仍然没有被保存.
在实施@Valikiliy 的建议后更新
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"4iK1kUNvKvoJVOKoivz/pcLAe6LY0cUJikQioxa8BIs=", "project"=>{"name"=>"Test", "description"=>"Test", "image"=>#<ActionDispatch::Http::UploadedFile:0x007fcd3a08d0b8 @tempfile=#<Tempfile:/var/folders/v_/98sxm8bn24qbqj_jmj40fv400000gn/T/RackMultipart20140610-36517-rgy95n>, @original_filename="minimize_http_requests.png", @content_type="image/png", @headers="Content-Disposition: form-data; name="project[image]"; filename="minimize_http_requests.png"
Content-Type: image/png
">}, "commit"=>"Update Project", "action"=>"update", "controller"=>"projects", "id"=>"16"}
更新:根据要求添加了新的表单代码
= simple_form_for(@project, :html => { :multipart => true }) do |f|
%ul
- @project.errors.full_messages.each do |error|
%li= error
.row
.small-1.columns
= f.label :name, :class => "left inline"
.small-11.columns
= f.text_field :name
.row
.small-1.columns
= f.label :description, :class => "left inline"
.small-11.columns
= f.text_area :description
.row
= f.simple_fields_for :assets do |a|
.small-1.columns
= a.label :image, :class => "left inline"
.small-11.columns
- if a.object.new_record?
= a.input :image, as: :file
- else
= image_tag a.object.image.url(:thumb)
= a.input_field '_destroy', as: :boolean
.row
.small-9.small-offset-1.columns
= f.submit nil ,:class => "button [radius round]"
更新
def project_params
params.require(:project).permit(:name, :description, images: [], assets_attributes: [:_destroy, :id, :image])
end
def find_project
@project = Project.find(params[:id])
@project.assets.build if %w[new edit].include?(action_name)
end
更新:添加模型代码
class Project < ActiveRecord::Base
has_many :assets, :dependent => :destroy
validates_presence_of :name, :on => :create, :update => "can't be blank"
validates_presence_of :description, :on => :create, :update => "can't be blank"
accepts_nested_attributes_for :assets, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
推荐答案
上面例子中要保存多个文件,不需要添加multiple:true选项,保存时会报错, 一个文件 - 一个记录 资产表.
To save multiple files in the above example you, do not need add multiple: true option, it will cause an error when saving, one file - one record assets table.
为了解决这个问题,您可以添加多个文件字段,如下所示:添加到控制器:
For resolve this, you can add multiple file fields, like this: add into controller:
def new
@project = Project.new
3.times{ @project.assets.build }
end
def edit
3.times{ @project.assets.build }
end
for while 列表
for while list
.permit(..., assets_attributes: [ :_destroy, :id, :image ])
并且像这样:
= f.simple_fields_for :assets do |a|
.small-1.columns
= a.label :image, :class => "left inline"
- if a.object.new_record?
.small-11.columns
= a.file_field :image
- else
.small-11.columns
= image_tag a.object.image.url(:thumb)
= a.input_field '_destroy', as: :boolean
如果您尝试像这样发送多个图像:
If you try to send multiple images like this:
# view
a.file_field :image, multiple: true
# controller
.permit(..., assets_attributes: [ :_destroy, :id, image: [] ])
这将导致错误,因为资产模型不知道如何处理图像数组.
This will cause an error because the Asset model does not know what to do with an array of images.
要同时保存多个文件,需要使用自己的处理程序,例如:
To save more than one file at the same time, you need to use your own handler, for example:
模型:添加images=
方法
def images=(files = [])
assets.create(image: f)
end
控制器:将 images: []
移到 assets_attributes 之外
controller: move images: []
outside of the assets_attributes
.permit(..., images: [], assets_attributes: [ :_destroy, :id ])
view:删除 fields_for 和嵌套属性
view: remove the fields_for and nested attributes
.row
.small-1.columns
=f.file_field :images, multiple: true
.row
= f.simple_fields_for :assets do |a|
.small-1.columns
= a.label :image, :class => "left inline"
....
这篇关于带有回形针的 Rails 4 多个文件附件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!