带有回形针的 Rails 4 多个文件附件 [英] Rails 4 multiple file attachments with Paperclip

查看:21
本文介绍了带有回形针的 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 中的回形针 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屋!

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