使用带有Rails carrierwave gem的ng-file-upload上传多个文件

时间:2015-08-13 02:38:50

标签: ruby-on-rails angularjs carrierwave ng-file-upload

我正在尝试将 ng-file-upload carrierwave 结合起来上传多个文件,但服务器端的控制器只收到一个文件(最后一项)选定的文件)。

客户端(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)打印数组[文件,文件,...] (浏览器:FireFox)。所以在客户端,它确实获得了所选的文件。在 ng-file-upload GitHub 页面上,它表示它支持html5的文件数组。

服务器端(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

其中@post.attaches是帖子的附件,而params[:file]是通过file中的Upload.upload参数从客户端发送的。

我想将一组文件存储到@post.attaches,但params[:file]只包含所选文件的一个文件。 puts params[:file]打印:

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

这表明params[:file]中只有一个文件。我不确定这个参数的使用是否有任何问题。

我怎么能解决这个问题?


以下是我的post.rb模型和attach_uploader.rb(由 carrierwave 创建)以供参考(如果需要):

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
数据库@post.attaches中的

posts列由

添加
rails g migration add_attaches_to_posts attaches:json

1 个答案:

答案 0 :(得分:1)

我终于找到了解决问题的方法。感谢carrierwavedanialfarid真棒ng-file-upload

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

toString()

然后在我的 rails 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 }); }

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 的所有文件。

我尝试使用{{1>} carrierwave 的列来存储一系列文件,但它没有用。所以我创建了一个名为params的文件表来存储我的文件

mount_uploaders

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


以下是有关设置的详细信息

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 (模特)

attachable

attach.rb(模特)

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

post.rb

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

我的默认附件用于图片。