Reputation: 12650
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
Upvotes: 3
Views: 543
Reputation: 19890
That error means that you are not returning valid JSON in your response. Please see the poject's server-side readme for more information. Another possibility is that your endpoint address is incorrect.
Upvotes: -1
Reputation: 3687
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"));
Upvotes: 2
Reputation: 2381
If you have posted your entire routes, then you are missing the endpoint route. Eg:
put "/avatar" => "your_controller#update"
ps: adapt the http verb on client or server side (put or post)
And your update
JSON outputs should look like (according to valums project wiki):
if @photo.save
render json: {:success => true, :src => @photo.image.url(:thumb)}
else
render json: @photo.errors.to_json
end
Upvotes: 1