Skip to content
Danial Farid edited this page Apr 23, 2015 · 17 revisions

Angular Code :

So here I am using Rails 4 with paperclip for attachments.

Showing below is the upload code for controller in Angularjs

// it's better to describe which file this code should be saved like;
// app/assets/javascripts/blabla1.js 
for (var i = 0; i < $files.length; i++) {
	var file = $files[i];
	$scope.upload = Upload.upload({
		url: 'server/upload/url',
		method: 'POST',
		data: mydata,//it is the data that's need to be sent along with image
		file: file,
		fileFormDataName: 'myEntity[image]',//myEntity is the name of the entity in which image is saved and image is the name of the attachment
		formDataAppender: function(fd, key, val) {
			if (angular.isArray(val)) {
				angular.forEach(val, function(v) {
					fd.append('myEntity['+key+']', v);
				});
			} else {
				fd.append('myEntity['+key+']', val);
			}
		}
	});
}

so, here my aim is to save data in a model with the attachment fields in it as per paperclip. Let us consider I want to save user with his image and the respective model is defined as

# probably a scene from db/schema.rb:
Table : User
  user_id : integer
  name : string
     # other fields related to attachment are being 
     # merged by using paperclip migration

so we can change the AngularJs controller code as

// if i'm not wrong, this should be same as blabla1.js:
for (var i = 0; i < $files.length; i++) {
	var file = $files[i];
	$scope.upload = Upload.upload({
		url: 'server/upload/url',
		method: 'POST',
		data: {name : $scope.name},
		file: file,
		fileFormDataName: 'user[image]',
		formDataAppender: function(fd, key, val) {
			if (angular.isArray(val)) {
				angular.forEach(val, function(v) {
					fd.append('user['+key+']', v);
				});
			} else {
				fd.append('user['+key+']', val);
			}
		}
	});
}

Here I save the attachment with name image Lets have a look on our controller code for Rails :

# let me guess, /app/controllers/user_controller.rb:
class UserController < ApplicationController
  def saveUser
    @user = Hotel.new(user_params)
    if @user.save
      render json: {success: true}
    else
      render json: @user.errors
    end  
  end  

  private 
    def user_params
      params.require(:user).permit(:name, :image)
    end 
end

Thats it, We are done.


Rails 4 and Angular File Upload 3 :

In the newest version of Angular File Upload (version 3 at the time of this writing), you should now use the fields options to send extra attributes, so you no longer need to use formDataAppender. To use the example above, this is how it should looks like now :

$scope.upload = function (files) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        $scope.upload = Upload.upload({
            url: 'server/upload/url',
            method: 'POST',
            fields: { 'user[name]': $scope.name },
            file: file,
            fileFormDataName: 'user[image]'
        });
    }
}

NOTE : This works on CarrierWave, Paperclip and Dragonfly as far as I could test.