使用带有Rails carrierwave gem的ng-file-upload上传多个文件
我正在尝试将ng-file-upload和carrierwave结合起来上传多个文件,但服务器端的控制器只接收一个文件(所选文件的最后一项)。
客户方( 参考 )
HTML
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)
打印Array [File,File,…] (浏览器:FireFox)。 因此,在客户端,它确实获取所选文件。 在ng-file-upload的GitHub页面上说它支持html5
的文件数组。
服务器端( 参考 )
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
是post的附件, params[:file]
是从Upload.upload
的file
参数从客户端发送的。
我想将一组文件存储到@post.attaches
,但params[:file]
只包含所选文件的一个文件。 puts params[:file]
打印:
#<ActionDispatch::Http::UploadedFile:0x007fddd1550300 @tempfile=#, @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
数据库posts
@post.attaches
列添加了
rails g migration add_attaches_to_posts attaches:json
我终于找到了解决问题的方法。 感谢carrierwave和danialfarid非常棒的文件上传 。
我的问题是我无法发送所有选定的文件。 我的解决方案是
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 }); }
然后在我的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
我创建了一个数组来存储来自params
所有文件。
我尝试使用带有mount_uploaders
的列来存储文件数组,但它不起作用。 所以我创建了一个名为attaches
的文件表来存储我的文件
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
用于存储postID和类型。 (这里我的附件属于我论坛中的一些post。)
如果需要,这里有一些关于设置的细节
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
然后在html
文件中可以有一个行代码
我的默认附件用于图像。
- Rails api用回形针
- 如何使用angularjs和ui路由器从rails获取实例变量?
- 角度资源没有调用我的错误回调函数
- 我们如何以干燥的方式使用带有angularjs的rails路由?
- 请求的资源上不存在“Access-Control-Allow-Origin”标头
- 如何从运行在不同端口上的本地AngularJS应用程序向本地Rails应用程序发出请求?
- 在rails上使用angularjs和ruby时出现未知的提供程序电子提供程序错误
- 这对于sinatra + angular.js +自定义提供程序的Oauth2工作流的概念是否正确?
- 确保用户使用cookieStore和AngularJS登录或注销的最佳实践