1

I'm trying to use angular to send a file as a param to rails, and then have rails save that file as a user attachment via paperclip. The furthest I've gotten is getting rails to upload something, but it ends up being a txt file with the single line 'object file'.

Here's the relevant Angular

a.uploadAnonRes = function(app){
  if(window.FileReader){ console.log("supported")};
  console.log(($('.anonUploadField'))[0].files);
  http = {
    method: "PUT",
    url: '/admin/upload_anon_res.json',
    params: {
      anon_file: btoa(($('.anonUploadField'))[0].files[0]),
      user_id: app.raw_app.user_id
    }
  };
  $http(http).success(function(data){
      console.log("success");
  });
};

Here's the relevant rails

def upload_anon_res
 user = User.find(params[:user_id])
 user.anon_resume = decode_res
 user.save
 respond_to do |format|
  format.json{ render json: user, root: false }
 end
end

def decode_res
 decoded_data = Base64.decode64(params[:anon_file])
 data = StringIO.new(decoded_data)
 return data
end

As a last note, the file types that I'm trying to work with are doc/docx. I'm trying to avoid adding new dependencies, but if there's no other good way, then so be it. I really appreciate any help/suggestions.

1 Answer 1

1

This answer helped me a lot, but I going to go through every part of it to have a complete answer.

Say you have a User model with a avatar attribute.

In your Angular View:

<input type="file" name="avatar" onchange="angular.element(this).scope().uploadFile(this.files)" />

In the Angular Controller:

    $scope.uploadFile = function(files) {
        var fd = new FormData();
        fd.append('user[avatar]', files[0]); // 'user[avatar]' is important, so that params[:user][:avatar] contains the file, as expected by Rails
        $http.put('/users.json', fd, { // The update method of the users controller
            withCredentials: true,
            headers: {
                'Content-Type': undefined,
                'X-CSRF-Token': $('meta[name=csrf-token]').attr('content')
            },
            transformRequest: angular.identity
        }).success(function(e) {
            console.log(e);
        }).error(function(e) {
            console.log(e);
        });
    };

In the UserController.rb:

class UserController < ApplicationController
  def update
    @user = User.find(params[:id])
    @user.assign_attributes(user_allowed_parameters)
    if (@user.save)
      render json: {msg: 'Successfully updated'}
    else
      render json: {msg: @user.errors.full_messages}, status: 500
    end
  end

  private

  def user_allowed_parameters
    params.fetch(:user, {}).permit(
      :first_name, 
      :last_name,
      :email,
      :avatar
    )
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

I just spent a good many hours looking for fd.append('user[avatar]', files[0]); . You are a saint!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.