I'm trying to get Valums uploader to work with my rails project and having a lot of difficulty.
I currently have a really simple upload process with Paperclip using the standard model and view... Model
class User
include Mongoid::Document
include Mongoid::Paperclip
has_mongoid_attached_file :image
Controller
def avatar
@user = current_user
respond_to do |format|
format.html
end
end
#working on the updateimage method
def update
file = params[:qqfile].is_a?(ActionDispatch::Http::UploadedFile) ? params[:qqfile] : params[:file]
@user = current_user
if @user.update_attributes(params[:user])
render :text => '{"success": true}', :content_type => "application/json"
else
render :text => @user.errors.to_json, :content_type => "application/json"
end
end
View
= form_for(@user, :as => @user, :url => '/updateimage', :html => { :method => :post, :multipart => true }) do |f|
#file-uploader
[email protected]
%img{:src => current_user.image}
= f.file_field :image
= f.submit
Soooooo... this all works, but when I try to use Valums jQuery:
$('#file-uploader').fineUploader({
debug: true,
autoSubmit: true,
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'],
sizeLimit: 1048576, // max size: 1MB
minSizeLimit: 0, // min size
multiple: false,
request: {
endpoint: '/updateimage',
paramsInBody: true
}
});
I get this:
undefined method `update_attributes' for nil:NilClass
I'd love to get this working, but I'm a little new to programming in general, so it's still quite an abstract thing for me. I'm happy to provide additional log info, just tell me where to find it.
Routes
admin_index GET /admin(.:format) admin#index
POST /admin(.:format) admin#create
new_admin GET /admin/new(.:format) admin#new
edit_admin GET /admin/:id/edit(.:format) admin#edit
admin GET /admin/:id(.:format) admin#show
PUT /admin/:id(.:format) admin#update
DELETE /admin/:id(.:format) admin#destroy
orders GET /orders(.:format) orders#index
POST /orders(.:format) orders#create
new_order GET /orders/new(.:format) orders#new
edit_order GET /orders/:id/edit(.:format) orders#edit
order GET /orders/:id(.:format) orders#show
PUT /orders/:id(.:format) orders#update
DELETE /orders/:id(.:format) orders#destroy
entries GET /entries(.:format) entries#index
POST /entries(.:format) entries#create
new_entry GET /entries/new(.:format) entries#new
edit_entry GET /entries/:id/edit(.:format) entries#edit
entry GET /entries/:id(.:format) entries#show
PUT /entries/:id(.:format) entries#update
DELETE /entries/:id(.:format) entries#destroy
home_index GET /home(.:format) home#index
POST /home(.:format) home#create
new_home GET /home/new(.:format) home#new
edit_home GET /home/:id/edit(.:format) home#edit
home GET /home/:id(.:format) home#show
PUT /home/:id(.:format) home#update
DELETE /home/:id(.:format) home#destroy
avatar /avatar(.:format) home#avatar
updateimage POST /updateimage(.:format) home#update
root / home#home
root / home#index
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize /users/auth/:provider(.:format) users/omniauth_callbacks#passthru {:provider=>/facebook/}
user_omniauth_callback /users/auth/:action/callback(.:format) users/omniauth_callbacks#(?-mix:facebook)
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel
user_registration POST /users(.:format) users/registrations#create
new_user_registration GET /users/sign_up(.:format) users/registrations#new
edit_user_registration GET /users/edit(.:format) users/registrations#edit
PUT /users(.:format) users/registrations#update
DELETE /users(.:format) users/registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
user GET /users/:id(.:format) users#show
Update: I think it's worth trying to leave users#update alone and create a separate action for file uploading.
As for the routes, FineUploader performs only POST requests so you have to add a new route because POST request to /users endpoint would trigger users#create action which is not what you want.
match '/avatar', :to => 'users#avatar', :via => :post
Furthermore, you have to handle file uploading on server side. This wiki page describes two methods. For instance, you can use rack-raw-upload gem and change controller code to the following:
def update
# this action does not handle AJAX file upload
# ...
end
def avatar
file = params[:qqfile].is_a?(ActionDispatch::Http::UploadedFile) ? params[:qqfile] : params[:file]
@user = current_user
if @user.update_attributes({ :image => file })
render :json => { :success => true }
else
render :json => { :success => false }
end
end
Note that there has to be a line in config/application.rb (if you use rack-raw-upload gem):
config.middleware.use 'Rack::RawUpload'
Moreover, it seems that paramsInBody should belong to request parameter:
$('#file-uploader').fineUploader({
request: {
endpoint: "/avatar",
paramsInBody: true
},
debug: true
})
The final note: CSRF token must be included in headers when making AJAX request in order to enable user authentication. It can be done by editing setHeaders function in fineuploader.js — add the following line to this function:
xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With