我知道Stackoverflow上有几篇帖子和几个关于这个主题的教程。然而,他们都没有设法解决我的问题,其中大多数也已经过时了。
我正在尝试使用Rails 4中的paperclip gem将多个图像添加到项目中。 当我尝试上传它时,我确实看到附加在params中的资产。
虽然它们似乎没有被添加到project_paramns中。
希望有人可以帮助我。
这是我的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\"\r\nContent-Type: image/jpeg\r\n">, #<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\"\r\nContent-Type: image/png\r\n">]}}, "commit"=>"Update Project", "action"=>"update", "controller"=>"projects", "id"=>"11"}
现在我的终端出现了错误:
Unpermitted parameters: asset
修改
@ pavan和@kiri thorat的答案的组合帮助我在project_params中显示了一些内容,它现在提供的输出是:
{"name"=>"Test", "description"=>"Test", "assets_attributes"=>{"0"=>{}}}
关于这里发生了什么的任何线索?
在@ kirithorat的最新更新之后,事情的参数方面似乎很好。
{"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\"\r\nContent-Type: image/jpeg\r\n">}}}, "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\"\r\nContent-Type: image/png\r\n">}, "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
答案 0 :(得分:17)
要保存上述示例中的多个文件,您不需要添加 multiple:true 选项,保存时会出错,一个文件 - 一个记录资产表。
要解决此问题,您可以添加多个文件字段,如下所示: 加入控制器:
def new
@project = Project.new
3.times{ @project.assets.build }
end
def edit
3.times{ @project.assets.build }
end
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
如果你尝试发送这样的多个图像:
# view
a.file_field :image, multiple: true
# controller
.permit(..., assets_attributes: [ :_destroy, :id, image: [] ])
这会导致错误,因为Asset模型不知道如何处理图像数组。
要同时保存多个文件,您需要使用自己的处理程序,例如:
模型:添加images=
方法
def images=(files = [])
assets.create(image: f)
end
controller:将images: []
移到assets_attributes
.permit(..., images: [], assets_attributes: [ :_destroy, :id ])
view:删除fields_for和嵌套属性
.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"
....
答案 1 :(得分:3)
project_params
应该是这样的
def project_params
params.require(:project).permit(:name, :description, assets_attributes: [:image])
end
此外,为什么您使用 protected
?我想你应该使用 private
。
答案 2 :(得分:3)
Project
和Asset
型号之间存在1-M关系,即
项目has_many资产
因此,在您的表单中,部分simple_fields_for
应该看起来像
= f.simple_fields_for :assets do |a|
注意 assets
复数而非asset
单数
在您当前的代码中,您使用simple_fields_for
与单数 asset
这就是为什么params
生成错误并且您收到asset
密钥的原因在params
哈希中,而不是接收assets_attributes
密钥,导致警告为Unpermitted parameters: asset
。
一旦您更正了表单部分,您将在表单提交时收到params
哈希中的正确密钥。现在,正如@Pavan指出我看到的下一个问题是你没有在控制器中正确地允许assets_attributes
。
您需要更新project_params
方法,如下所示:
def project_params
params.require(:project).permit(:name, :description, assets_attributes: [:image])
end
注意 assets_attributes
复数中的assets
<强>更新强>
您需要在@project.assets.build
的{{1}}和new
操作中添加edit
,才能在ProjectsController
和{{{{}}中查看资源字段1}}查看。
另外,我建议在new
中edit
的允许属性列表中添加:id
,如下所示:
assets_attributes
我看到的project_params
中出现的问题很少
在上传文件时,您应在表单中指定 params.require(:project).permit(:name, :description, assets_attributes: [:id, :image])
。
更改
form partial
要
:html => {:multipart => true}
项目has_many资产,每个= simple_form_for @project do |f|
记录只有一个= simple_form_for @project, :html => {:multipart => true} do |f|
,因此请删除asset
。另外,在使用image
时,建议使用multiple: true
辅助方法上传文件。
更改
simple_form
要
simple_form