Rails Valums Ajax 上传
Posted
技术标签:
【中文标题】Rails Valums Ajax 上传【英文标题】:Rails Valums Ajax Upload 【发布时间】:2013-02-21 15:56:45 【问题描述】:我正在尝试让 Valums 上传器与我的 Rails 项目一起工作,但遇到了很多困难。
我目前有一个非常简单的使用 Paperclip 上传过程,使用标准模型和视图... 型号
class User
include Mongoid::Document
include Mongoid::Paperclip
has_mongoid_attached_file :image
控制器
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
查看
= form_for(@user, :as => @user, :url => '/updateimage', :html => :method => :post, :multipart => true ) do |f|
#file-uploader
=@user.firstname
%img:src => current_user.image
= f.file_field :image
= f.submit
Soooooo... 这一切都有效,但是当我尝试使用 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
);
我明白了:
undefined method `update_attributes' for nil:NilClass
我很乐意让它工作,但我对一般编程有点陌生,所以它对我来说仍然是一件相当抽象的事情。我很乐意提供额外的日志信息,请告诉我在哪里可以找到它。
路线
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
【问题讨论】:
显示rake routes
命令的输出。
已发布路线。 注意:当我的端点是“用户”时,它几乎是正确的。意思是,我在控制台中得到了回报,但我实际上并没有更新任何信息……不知道为什么。目前“用户”用于更新用户配置文件中的所有字段,而不仅仅是用户头像...
注意:也可以使用 Rack::RawUpload gem。
【参考方案1】:
该错误意味着您没有在响应中返回有效的 JSON。请参阅项目的server-side readme 了解更多信息。另一种可能是你的端点地址不正确。
【讨论】:
如何调试端点地址?端点与控制器功能不一样吗? '家/头像'? 我不是 Rails 人,所以我无法帮助你。只有您可以确定端点的地址是什么。我将从查看 HTTP 请求/响应开始。 Ray,感谢您的反馈,但如果您不能提供 Rails 特定的答案,我无法接受。我可以通过快速的 Google 搜索轻松找到您提供的内容。 我理解凯文,但是解决你问题的方法真的很简单。您没有指定正确的端点地址,或者您指定了正确的端点地址,但您的服务器端代码未返回有效的 JSON。您如何确定您的代码是否返回了有效的 JSON?查看原始响应并使用jsonlint。如果您的端点是错误的,那么没有人可以帮助您。您需要找出服务器的正确地址。此外,您的响应内容类型应该是 text/plain,而不是 application/json。这在自述文件中有详细说明。 谢谢,雷。也许问题可能出在我的路线文件中(我知道你不是 Rails 人)......如果你有时间,我是 Rails/编程的新手,你能告诉我为什么响应应该是文本而不是json?【参考方案2】:如果您发布了您的全部路线,那么您错过了端点路线。例如:
put "/avatar" => "your_controller#update"
ps:在客户端或服务器端(放置或发布)调整http动词
您的update
JSON 输出应该看起来像(根据 valums 项目 wiki):
if @photo.save
render json: :success => true, :src => @photo.image.url(:thumb)
else
render json: @photo.errors.to_json
end
【讨论】:
能给我一个更合适的控制器方法吗?我正在使用carrierwave和mongodb...【参考方案3】:更新:我认为值得尝试不理会users#update
并创建一个单独的文件上传操作。
至于路由,FineUploader 仅执行 POST
请求,因此您必须添加新路由,因为 POST
请求到 /users
端点会触发 users#create
操作,这不是您想要的。
match '/avatar', :to => 'users#avatar', :via => :post
此外,您必须在服务器端处理文件上传。 This wiki page 描述了两种方法。例如,您可以使用rack-raw-upload
gem 并将控制器代码更改为以下内容:
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
注意config/application.rb
中必须有一行(如果您使用rack-raw-upload
gem):
config.middleware.use 'Rack::RawUpload'
另外,看来paramsInBody
应该属于request
参数:
$('#file-uploader').fineUploader(
request:
endpoint: "/avatar",
paramsInBody: true
,
debug: true
)
最后一点: 发出 AJAX 请求时,CSRF 令牌必须包含在标头中,以启用用户身份验证。可以通过编辑fineuploader.js
中的setHeaders
函数来完成——在该函数中添加以下行:
xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"));
【讨论】:
我觉得这更接近了......但我仍然收到错误 - 提交时用户已注销...... 我正在尝试一些不同的东西,但我得到了诸如“未定义方法'update_attributes'”之类的东西......我不知道该去哪里。如果你能引导我完成,我会尽我所能。 @KevinBrown 用户注销时模型字段会发生什么?它们的值是否正确更新? 不这么认为。我做了更多的傻事,现在我得到了Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
我有机会进一步检查。你能帮我吗?您的代码有效(没有 AJAX/VALUMS)并且没有 .merge。我正在使用 mongo——这会改变事情吗?为什么此功能适用于常规表单提交而不适用于值?!我没有正确配置 rawupload 吗?以上是关于Rails Valums Ajax 上传的主要内容,如果未能解决你的问题,请参考以下文章