使用带有 Rails carrierwave gem 的 ng-file-upload 上传多个文件
Using ng-file-upload with Rails carrierwave gem to upload multiple files
我正在尝试结合 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)
打印 Array[File, File, ...](浏览器:FireFox)。所以在客户端它确实获得了选定的文件。在 GitHub 页面上 ng-file-upload 说它支持 html5
.[=35 的文件数组=]
服务器端(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
是 post 的附件,而 params[:file]
是由 Upload.upload
中的 file
参数从客户端发送的。
我想将一组文件存储到 @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
数据库 posts
中的 和 @post.attaches
列由
添加
rails g migration add_attaches_to_posts attaches:json
我终于找到了解决问题的方法。感谢 carrierwave and danialfarid's awesome ng-file-upload。
我的问题是我无法发送所有选定的文件。我的解决方案是
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
});
}
然后在我的railscontroller.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
of carrierwave 的列来存储文件数组,但没有成功。所以我创建了一个名为 attaches
的文件 table 来存储我的文件
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
用于存储 post id 和类型。 (这里我的附件属于我论坛中的一些 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
文件中可以有一行代码
<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>
我的默认附件用于图像。
我正在尝试结合 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)
打印 Array[File, File, ...](浏览器:FireFox)。所以在客户端它确实获得了选定的文件。在 GitHub 页面上 ng-file-upload 说它支持 html5
.[=35 的文件数组=]
服务器端(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
是 post 的附件,而 params[:file]
是由 Upload.upload
中的 file
参数从客户端发送的。
我想将一组文件存储到 @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
数据库 posts
中的 和 @post.attaches
列由
rails g migration add_attaches_to_posts attaches:json
我终于找到了解决问题的方法。感谢 carrierwave and danialfarid's awesome ng-file-upload。
我的问题是我无法发送所有选定的文件。我的解决方案是
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
});
}
然后在我的railscontroller.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
of carrierwave 的列来存储文件数组,但没有成功。所以我创建了一个名为 attaches
的文件 table 来存储我的文件
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
用于存储 post id 和类型。 (这里我的附件属于我论坛中的一些 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
文件中可以有一行代码
<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>
我的默认附件用于图像。