使用Paperclip Rails 4多个文件附件 [英] Rails 4 multiple file attachments with Paperclip

查看:146
本文介绍了使用Paperclip Rails 4多个文件附件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道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中的paperclip gem将多个图像添加到项目中。
当我尝试上传它时,我确实看到附加在params中的资产。

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\"\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中显示了一些内容,它现在提供的输出是:

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\"\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


推荐答案

保存多个文件在上面的示例中,您不需要添加 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.

要解决此问题,您可以添加多个文件字段,如下所示:
add into controller:

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 list

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:

model:添加 images = 方法

model: add the images= method

def images=(files = [])
  assets.create(image: f)
end

控制器:移动图片:[] 在assets_attributes之外

controller: move images: [] outside of the assets_attributes

.permit(..., images: [], assets_attributes: [ :_destroy, :id ])

查看:删除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"
....

这篇关于使用Paperclip Rails 4多个文件附件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆