采用NG-文件上传使用Rails carrierwave宝石上传多个文件 [英] Using ng-file-upload with Rails carrierwave gem to upload multiple files

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

问题描述

我想结合的 NG-文件上传 carrierwave 即可上传多个文件,但在服务器端控制器接收只有一个文件(的最后一个项目所选的文件)。

客户端(参考

HTML

<按钮式=文件NG-模式=文件NGF选NGF海报=真 >&上传LT; /按钮>

JS

VAR上传=功能(文件,内容){
    返回Upload.upload({
        网址:'MY_CONTROLLER_URL',
        文件:文件,文件//是多个文件数组
        字段:{'MY_KEY':'MY_CONTENT'}
    })。进度(功能(EVT){
        VAR progressPercentage = parseInt函数(100.0 * evt.loaded / evt.total);
        的console.log('进步:'+ progressPercentage +'%'+ evt.config.file.name);
    })。成功(功能(数据,状态,头,配置){
        的console.log('文件'+ config.file.name +'。上传的回应:+数据);
    })错误(功能(数据,状态,头,配置){
        的console.log('错误状态:'+状态);
    });
};

的console.log(文件)打印的数组[文件,文件,...] 的(浏览器:Firefox)。因此,在客户端它得到所选文件。在 GitHub上页中的 NG-文件上传说,它支持的文件数组 HTML5

服务器端(参考

posts_controller.rb

DEF创建
    @post = Post.new(post_params)
    @ post.attaches =参数[:文件]
    @ post.save
    渲染JSON:@post
结束私人的
高清post_params
    params.require(:后).permit(:内容:文件)
结束

其中, @ post.attaches 是一个帖子的附件和 PARAMS [:文件] 从客户端发送侧文件参数 Upload.upload

我要文件的数组存储到 @ post.attaches ,但 PARAMS [:文件] 包含所选文件中的一个文件。
看跌期权PARAMS [:文件] 打印:

 #< ActionDispatch :: HTTP :: UploadedFile的:0x007fddd1550300 @tempfile =#<它视为:/tmp/RackMultipart20150812-2754-vchvln.jpg> ;, @ original_filename =黑色 - 金属齿轮瑞星-Wallpaper.jpg,@ CONTENT_TYPE =图像/ JPEG,@标题=内容处置:表格数据;名称= \\文件\\;文件名= \\黑色金属Gear-瑞星-Wallpaper.jpg \\\\ r \\ nContent-类型:image / JPEG \\ r \\ n>

这表明,在只有一个文件PARAMS [:文件] 。我不知道是否有什么不对这个参数的用法。

我怎么能解决这个问题?

结果
这里是我的 post.rb 模式和 attach_uploader.rb (所创造的 carrierwave )以如果需要参考:

post.rb

类帖子< ActiveRecord的::基地
    mount_uploaders:武官,AttachUploader
结束

attach_uploader.rb

类AttachUploader< CarrierWave ::上传::基地
    存储:文件
    高清store_dir
        上传/#{} model.class.to_s.underscore /#{} mounted_as /#{} model.id
    结束
结束

@ post.attaches 在数据库列帖子

添加

导轨摹迁移add_attaches_to_posts附:JSON


解决方案

我终于找到一个方法来解决我的问题。感谢 carrierwave 并的 danialfarid 的真棒 NG-文件上传

我的问题是我无法发送所有选定的文件。我的解决方案是

VAR上传=功能(文件){
    变种名称= [];
    对于(VAR I = 0; I< files.length ++ I)
        names.push(文件[I]。名称);
    返回Upload.upload({
        网址:'/ API / V1 /帖,
        文件:文件,
        fileFormDataName:名称
    });
}

然后在我的 controller.rb

file_arr = params.values​​.find_all {|值| value.class == ActionDispatch :: HTTP :: UploadedFile的}如果@ post.save
  除非file_arr.empty?
    file_arr.each {|附加|
      @attach = At​​tach.new
      @ attach.filename =附加
      @ attach.attachable = @post
      @ attach.save
    }
  结束
  渲染JSON:@post
结束

我创建了一个数组来我的所有文件从存储 PARAMS

我试图用一个柱 carrierwave 的mount_uploaders 来存储文件的数组,但没有奏效。所以,我创建一个名为文件表华武官来存储我的文件

类CreateAttaches< ActiveRecord的::迁移
  高清变化
    CREATE_TABLE:华武官做| T |
      t.string:文件名
      t.references:可连接,多态:真
      t.timestamps空:假的
    结束
  结束
结束

其中,用于存储的帖子ID和类型。 (在这里,我的附件属于我的论坛上一些后)。

结果
下面是有关设置的一些细节,如果需要

attach.rb (模型)

类附加< ActiveRecord的::基地
  mount_uploader:文件名,AttachUploader
  belongs_to的:可连接,多态=>真正
结束

post.rb (模型)

类帖子< ActiveRecord的::基地
  的has_many:高度重视,如:附着,依赖:摧毁
结束

post_serializer.rb

类PostSerializer< ::加载ActiveModel串行
  的has_many:华武官
结束

attach_serializer.rb

类AttachSerializer< ::加载ActiveModel串行
  属性:URL,:名称  高清网址
    object.filename.url
  结束  DEF名称
    object.filename_identifier
  结束
结束

然后在 HTML 文件可以有一排code

< D​​IV NG重复=附上post.attaches>
    < IMG NG-SRC ={{attach.url}}类型=文件HEIGHT =180WIDTH =320接受=图像/ */>
    <目标=_自我NG-秀=attach.url的href ={{attach.url}}下载={{attach.name}}> {{attach.name}}< p>&下; / p>&下; / A>
< / DIV>

在我的默认附件用于图像。

I'm trying to combine ng-file-upload and carrierwave to upload multiple files, but the controller on server side receives only one file (the last item of the selected files).

Client side (reference)

html

<button type="file" ng-model="files" ngf-select ngf-multiple="true">Upload</button>

js

var upload = function (files, content) {
    return Upload.upload({
        url: 'MY_CONTROLLER_URL',
        file: files, // files is an array of multiple files
        fields: { 'MY_KEY': 'MY_CONTENT' }
    }).progress(function (evt) {
        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
        console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
    }).success(function (data, status, headers, config) {
        console.log('files ' + config.file.name + ' uploaded. Response: ' + data);
    }).error(function (data, status, headers, config) {
        console.log('error status: ' + status);
    });
};

console.log(files) prints Array[File, File, ...] (Browser: FireFox). So on client side it does get the selected files. On the GitHub page of ng-file-upload says it supports array of files for html5.

Server side (reference)

posts_controller.rb

def create
    @post = Post.new(post_params)
    @post.attaches = params[:file]
    @post.save
    render json: @post
end

private
def post_params
    params.require(:post).permit(:content, :file)
end

where @post.attaches is the attachments of a post and params[:file] is sent from client side by file parameter in Upload.upload.

I want to store an array of files into @post.attaches, but params[:file] contains only one file of the selected files. puts params[:file] prints:

#<ActionDispatch::Http::UploadedFile:0x007fddd1550300 @tempfile=#<Tempfile:/tmp/RackMultipart20150812-2754-vchvln.jpg>, @original_filename="Black-Metal-Gear-Rising-Wallpaper.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"file\"; filename=\"Black-Metal-Gear-Rising-Wallpaper.jpg\"\r\nContent-Type: image/jpeg\r\n">

This shows that there is only one file in params[:file]. I'm not sure if there is anything wrong with the usage of this parameter.

How could I solve this problem?


Here is my post.rb model and attach_uploader.rb (created by carrierwave) for reference if needed:

post.rb

class Post < ActiveRecord::Base
    mount_uploaders :attaches, AttachUploader
end

attach_uploader.rb

class AttachUploader < CarrierWave::Uploader::Base
    storage :file
    def store_dir
        "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
end

and @post.attaches column in database posts is added by

rails g migration add_attaches_to_posts attaches:json

解决方案

I finally found a way to solve my problem. Thanks for carrierwave and danialfarid's awesome ng-file-upload.

My problem was I couldn't send all selected files. My solution was

var upload = function (files) {
    var names = [];
    for (var i = 0; i < files.length; ++i)
        names.push(files[i].name);
    return Upload.upload({
        url: '/api/v1/posts',
        file: files,
        fileFormDataName: names
    });
}

Then in my rails controller.rb

file_arr = params.values.find_all { |value| value.class == ActionDispatch::Http::UploadedFile }

if @post.save
  unless file_arr.empty?
    file_arr.each { |attach|
      @attach = Attach.new
      @attach.filename = attach
      @attach.attachable = @post
      @attach.save
    }
  end
  render json: @post
end

I created an array to store all my files from params.

I tried to use a column with mount_uploaders of carrierwave to store an array of files, but it didn't work. So I create a file table called attaches to store my files

class CreateAttaches < ActiveRecord::Migration
  def change
    create_table :attaches do |t|
      t.string :filename
      t.references :attachable, polymorphic: true
      t.timestamps null: false
    end
  end
end

where attachable is used to store the post id and type. (Here my attachments belong to some post in my forum.)


Here is some details about setting if needed

attach.rb (model)

class Attach < ActiveRecord::Base
  mount_uploader :filename, AttachUploader
  belongs_to :attachable, :polymorphic => true
end

post.rb (model)

class Post < ActiveRecord::Base
  has_many :attaches, as: :attachable, dependent: :destroy
end

post_serializer.rb

class PostSerializer < ActiveModel::Serializer
  has_many :attaches
end

attach_serializer.rb

class AttachSerializer < ActiveModel::Serializer
  attributes :url, :name

  def url
    object.filename.url
  end

  def name
    object.filename_identifier
  end
end

Then in html file can have a row code

<div ng-repeat="attach in post.attaches">
    <img ng-src="{{attach.url}}" type="file" height="180" width="320" accept="image/*"/>
    <a target="_self" ng-show="attach.url" href="{{attach.url}}" download="{{attach.name}}">{{attach.name}}<p></p></a>
</div>

where my default attachments are used for images.

这篇关于采用NG-文件上传使用Rails carrierwave宝石上传多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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