Rails Valums Ajax上传

时间:2013-03-06 17:52:17

标签: ruby-on-rails ajax upload fine-uploader

我正在尝试使用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

3 个答案:

答案 0 :(得分:2)

更新:我认为值得尝试单独留下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令牌才能启用用户身份验证。可以通过编辑setHeaders中的fineuploader.js函数来完成 - 将以下行添加到此函数中:

xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"));

答案 1 :(得分:1)

如果您已发布整个路线,那么您将错过端点路线。例如:

put "/avatar" => "your_controller#update"

ps:在客户端或服务器端调整http动词(put或post)

你的update JSON输出应该是这样的(根据valums项目维基):

if @photo.save
  render json: {:success => true, :src => @photo.image.url(:thumb)}
else
  render json: @photo.errors.to_json
end

答案 2 :(得分:-1)

该错误意味着您没有在响应中返回有效的JSON。有关详细信息,请参阅项目server-side readme。另一种可能是您的端点地址不正确。