2014-02-12 83 views
0

我试图实现Jcrop在我的应用程序,并不断收到以下错误:Rails的Carrierwave NoMethodError

NoMethodError in PeopleController#update 
undefined method `body' for nil:NilClass 

我使用Rails 4.0.2,红宝石2.0.0p0,引导2.3.2,Jcrop 0.9.12,Rmagick 2.13.2

奇怪的是,如果我重新加载用户的页面,裁剪后的图片会保存到S3并显示在用户界面中。但是,每当我尝试裁剪图片时都会发生此错误。

这是我的人物模型。我在**中标记了该行,并在错误生成时在浏览器中突出显示。

class Person < ActiveRecord::Base 
    validates_presence_of :fname, :lname, :company, :department, :title, :work_phone, :mobile, :office, :address, :city, :state, :zipcode, :country, :suite, :column 

    attr_accessor :crop_x, :crop_y, :crop_w, :crop_h 

    mount_uploader :photo, PhotoUploader 

    after_update :crop_photo 

    def crop_photo 
    **photo.recreate_versions! if crop_x.present?** 
    end 
end 

这里是我的PhotoUploader.rb文件:

# encoding: utf-8 

class PhotoUploader < CarrierWave::Uploader::Base 

    # Include RMagick or MiniMagick support: 
    include CarrierWave::RMagick 
    # include CarrierWave::MiniMagick 

    # Choose what kind of storage to use for this uploader: 
    # storage :file 
    storage :fog 

    include CarrierWave::MimeTypes 
    process :set_content_type 

    # Override the directory where uploaded files will be stored. 
    # This is a sensible default for uploaders that are meant to be mounted: 
    def store_dir 
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 
    end 

    # Provide a default URL as a default if there hasn't been a file uploaded: 
    def default_url 
    # For Rails 3.1+ asset pipeline compatibility: 
    ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 

    # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 
    end 

    # Process files as they are uploaded: 
    # process :scale => [200, 300] 
    # 
    # def scale(width, height) 
    # # do something 
    # end 

    # Create different versions of your uploaded files: 

    version :large do 
    process :resize_to_limit => [600, 600] 
    end 

    version :thumb do 
    process :crop 
    process :resize_to_limit => [200, 200] 
    end 

    def crop 
    if model.crop_x.present? 
     resize_to_limit(600, 600) 
     manipulate! do |img| 
     x = model.crop_x.to_i 
     y = model.crop_y.to_i 
     w = model.crop_w.to_i 
     h = model.crop_h.to_i 
     img.crop!(x, y, w, h) 
     end 
    end 
    end 

    after :store, :remove_original_file 

    def remove_original_file(p) 
    if self.version_name.nil? 
     self.file.delete if self.file.exists? 
    end 
    end 

    # Add a white list of extensions which are allowed to be uploaded. 
    # For images you might use something like this: 
    # def extension_white_list 
    # %w(jpg jpeg gif png) 
    # end 

    # Create random filename the filename of the uploaded files: 
    def filename 
    "#{secure_token(10)}.#{file.extension}" if original_filename.present? 
    end 

    protected 
    def secure_token(length=16) 
    var = :"@#{mounted_as}_secure_token" 
    model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.hex(length/2)) 
    end 
end 

这里是我的控制器更新动作:

def update 
    # respond_to do |format| 
     if @person.update(person_params) 
     if params[:person][:photo].present? 
      render :crop 
     else 
      redirect_to @person, notice: "Successfully updated person." 
     end 
     # format.html { redirect_to @person, notice: 'Person was successfully updated.' } 
     # format.json { head :no_content } 
     # else 
     # format.html { render action: 'edit' } 
     # format.json { render json: @person.errors, status: :unprocessable_entity } 
     end 
    # end 
    end 

这里是我的形式:

<%= simple_form_for @person, :html => { :class => 'form-horizontal', :multipart => 'true' } do |f| %> 


    <div class="upload"> 
    <!-- <div class="photo"> --> 
     <%= image_tag @person.photo.url(:thumb).to_s %> 
    <!-- </div> --> 
     <%= f.file_field :photo, label: 'Upload Photo' %> 
    </div> 

    <%= f.input :ntid, label: 'NTID:', :input_html => { :readonly => true } %> 
    <%= f.input :fname, label: 'First Name:' %> 
    <%= f.input :mname, label: 'Middle Name:' %> 
    <%= f.input :lname, label: 'Last Name:' %> 
    <%= f.input :company, label: 'Company:' %> 
    <%= f.input :department, label: 'Department:' %> 
    <%= f.input :title, label: 'Title:' %> 
    <%= f.input :email, label: 'E-Mail:' %> 
    <%= f.input :work_phone, label: 'Work Phone:' %> 
    <%= f.input :mobile, label: 'Mobile Phone:' %> 
    <%= f.input :fax, label: 'FAX:' %> 
    <%= f.input :office, label: 'Office:' %> 
    <%= f.input :address, label: 'Address:' %> 
    <%= f.input :city, label: 'City:' %> 
    <%= f.input :state, collection: [ "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming" ], label: 'State:' %> 
    <%= f.input :zipcode, label: 'Zipcode:' %> 
    <%= f.input :country, priority: [ "US" ], collection: [ "Canada", "Ireland", "India", "US"], label: 'Country:' %> 
    <%= f.input :suite, label: 'Suite:' %> 
    <%= f.input :column, label: 'Column:' %> 
    <%= f.input :assistant, label: 'Assistant:' %> 

    <div class="form-actions"> 
    <%= f.button :submit, :class => 'btn-primary' %> 
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")), 
       people_path, :class => 'btn' %> 
    </div> 
<% end %> 

这是我在我的development.log中看到的

Started PATCH "/people/3" for 127.0.0.1 at 2014-02-13 14:47:12 -0600 
Processing by PeopleController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"et3p2hPLTKvVh7aAkD9OCq8IHJe9kZ52L/WFiNmity0=", "person"=>{"crop_x"=>"200", "crop_y"=>"0", "crop_w"=>"400", "crop_h"=>"400"}, "commit"=>"Crop Photo", "id"=>"3"} 
    [1m[36mPerson Load (1.5ms)[0m [1mSELECT "people".* FROM "people" WHERE "people"."id" = $1 LIMIT 1[0m [["id", "3"]] 
    [1m[35m (1.3ms)[0m BEGIN 
    [1m[36m (0.2ms)[0m [1mROLLBACK[0m 
Completed 500 Internal Server Error in 1430ms 

NoMethodError (undefined method `body' for nil:NilClass): 
    app/models/person.rb:11:in `crop_photo' 
    app/controllers/people_controller.rb:49:in `update' 

这里是我的全部跟踪:

carrierwave (0.9.0) lib/carrierwave/storage/fog.rb:227:in `read' 
carrierwave (0.9.0) lib/carrierwave/uploader/cache.rb:77:in `sanitized_file' 
carrierwave (0.9.0) lib/carrierwave/uploader/cache.rb:116:in `cache!' 
carrierwave (0.9.0) lib/carrierwave/uploader/versions.rb:225:in `recreate_versions!' 
app/models/person.rb:11:in `crop_photo' 
activesupport (4.0.2) lib/active_support/callbacks.rb:386:in `_run__335866053033251740__update__callbacks' 
activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks' 
activerecord (4.0.2) lib/active_record/callbacks.rb:310:in `update_record' 
activerecord (4.0.2) lib/active_record/timestamp.rb:70:in `update_record' 
activerecord (4.0.2) lib/active_record/persistence.rb:477:in `create_or_update' 
activerecord (4.0.2) lib/active_record/callbacks.rb:302:in `block in create_or_update' 
activesupport (4.0.2) lib/active_support/callbacks.rb:383:in `_run__335866053033251740__save__callbacks' 
activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks' 
activerecord (4.0.2) lib/active_record/callbacks.rb:302:in `create_or_update' 
activerecord (4.0.2) lib/active_record/persistence.rb:106:in `save' 
activerecord (4.0.2) lib/active_record/validations.rb:51:in `save' 
activerecord (4.0.2) lib/active_record/attribute_methods/dirty.rb:32:in `save' 
activerecord (4.0.2) lib/active_record/transactions.rb:270:in `block (2 levels) in save' 
activerecord (4.0.2) lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status' 
activerecord (4.0.2) lib/active_record/connection_adapters/abstract/database_statements.rb:200:in `transaction' 
activerecord (4.0.2) lib/active_record/transactions.rb:209:in `transaction' 
activerecord (4.0.2) lib/active_record/transactions.rb:323:in `with_transaction_returning_status' 
activerecord (4.0.2) lib/active_record/transactions.rb:270:in `block in save' 
activerecord (4.0.2) lib/active_record/transactions.rb:281:in `rollback_active_record_state!' 
activerecord (4.0.2) lib/active_record/transactions.rb:269:in `save' 
activerecord (4.0.2) lib/active_record/persistence.rb:230:in `block in update' 
activerecord (4.0.2) lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status' 
activerecord (4.0.2) lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `block in transaction' 
activerecord (4.0.2) lib/active_record/connection_adapters/abstract/database_statements.rb:210:in `within_new_transaction' 
activerecord (4.0.2) lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `transaction' 
activerecord (4.0.2) lib/active_record/transactions.rb:209:in `transaction' 
activerecord (4.0.2) lib/active_record/transactions.rb:323:in `with_transaction_returning_status' 
activerecord (4.0.2) lib/active_record/persistence.rb:228:in `update' 
app/controllers/people_controller.rb:49:in `update' 
actionpack (4.0.2) lib/action_controller/metal/implicit_render.rb:4:in `send_action' 
actionpack (4.0.2) lib/abstract_controller/base.rb:189:in `process_action' 
actionpack (4.0.2) lib/action_controller/metal/rendering.rb:10:in `process_action' 
actionpack (4.0.2) lib/abstract_controller/callbacks.rb:18:in `block in process_action' 
activesupport (4.0.2) lib/active_support/callbacks.rb:413:in `_run__922881453698794513__process_action__callbacks' 
activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks' 
actionpack (4.0.2) lib/abstract_controller/callbacks.rb:17:in `process_action' 
actionpack (4.0.2) lib/action_controller/metal/rescue.rb:29:in `process_action' 
actionpack (4.0.2) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action' 
activesupport (4.0.2) lib/active_support/notifications.rb:159:in `block in instrument' 
activesupport (4.0.2) lib/active_support/notifications/instrumenter.rb:20:in `instrument' 
activesupport (4.0.2) lib/active_support/notifications.rb:159:in `instrument' 
actionpack (4.0.2) lib/action_controller/metal/instrumentation.rb:30:in `process_action' 
actionpack (4.0.2) lib/action_controller/metal/params_wrapper.rb:245:in `process_action' 
activerecord (4.0.2) lib/active_record/railties/controller_runtime.rb:18:in `process_action' 
actionpack (4.0.2) lib/abstract_controller/base.rb:136:in `process' 
actionpack (4.0.2) lib/abstract_controller/rendering.rb:44:in `process' 
actionpack (4.0.2) lib/action_controller/metal.rb:195:in `dispatch' 
actionpack (4.0.2) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch' 
actionpack (4.0.2) lib/action_controller/metal.rb:231:in `block in action' 
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:80:in `call' 
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:80:in `dispatch' 
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:48:in `call' 
actionpack (4.0.2) lib/action_dispatch/journey/router.rb:71:in `block in call' 
actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `each' 
actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `call' 
actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:680:in `call' 
rack (1.5.2) lib/rack/etag.rb:23:in `call' 
rack (1.5.2) lib/rack/conditionalget.rb:35:in `call' 
rack (1.5.2) lib/rack/head.rb:11:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/params_parser.rb:27:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/flash.rb:241:in `call' 
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context' 
rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/cookies.rb:486:in `call' 
activerecord (4.0.2) lib/active_record/query_cache.rb:36:in `call' 
activerecord (4.0.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call' 
activerecord (4.0.2) lib/active_record/migration.rb:369:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call' 
activesupport (4.0.2) lib/active_support/callbacks.rb:373:in `_run__3121532127090690729__call__callbacks' 
activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks' 
actionpack (4.0.2) lib/action_dispatch/middleware/callbacks.rb:27:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/reloader.rb:64:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/remote_ip.rb:76:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call' 
railties (4.0.2) lib/rails/rack/logger.rb:38:in `call_app' 
railties (4.0.2) lib/rails/rack/logger.rb:20:in `block in call' 
activesupport (4.0.2) lib/active_support/tagged_logging.rb:67:in `block in tagged' 
activesupport (4.0.2) lib/active_support/tagged_logging.rb:25:in `tagged' 
activesupport (4.0.2) lib/active_support/tagged_logging.rb:67:in `tagged' 
railties (4.0.2) lib/rails/rack/logger.rb:20:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/request_id.rb:21:in `call' 
rack (1.5.2) lib/rack/methodoverride.rb:21:in `call' 
rack (1.5.2) lib/rack/runtime.rb:17:in `call' 
activesupport (4.0.2) lib/active_support/cache/strategy/local_cache.rb:83:in `call' 
rack (1.5.2) lib/rack/lock.rb:17:in `call' 
actionpack (4.0.2) lib/action_dispatch/middleware/static.rb:64:in `call' 
rack (1.5.2) lib/rack/sendfile.rb:112:in `call' 
railties (4.0.2) lib/rails/engine.rb:511:in `call' 
railties (4.0.2) lib/rails/application.rb:97:in `call' 
rack (1.5.2) lib/rack/lock.rb:17:in `call' 
rack (1.5.2) lib/rack/content_length.rb:14:in `call' 
rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service' 
/Users/scottsipiora/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service' 
/Users/scottsipiora/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run' 
/Users/scottsipiora/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread' 

上我能做些什么来解决这个问题的任何想法?

由于

+0

可以显示你的表单吗? – Arun

+0

某处你调用对象的方法'body',而那个对象是'nil'。尝试找到它在哪里,也许在布局或更新视图中的其他地方? –

+0

嗨塞尔吉奥,我到处搜索“身体”,只发现有效的和引用。当我查看我的development.log(我已经添加)时,我认为这个问题是由我在我的控制器(我现在正在显示)中注释掉的一些行引起的。我评论他们,因为我有点小事,并不认为他们是需要的,当我把他们删除他们的问题,我已经修复。所以它好像在寻找“更新为HTML”的代码,但我已经评论了它,因为当它们在那里时,我在PeopleController#update中得到了“AbstractController :: DoubleRenderError” –

回答

0

的实际代码触发的例外是在Carrierwave repository。 回溯到where它实际上被称为告诉它试图缓存由于某种原因不存在的文件。下一步调试将实际上确保您尝试重新裁剪的文件存在。我认为,因为你在after_update钩子中这样做,你的文件可能不存在你所需要的状态。

+0

当我注释掉我的模型的那一行时,我没有收到任何错误(这很好)但是,图像也没有被裁剪Humm ... –

+0

我无法为你调试你的代码,我只能告诉你你应该在哪里寻找 –

+0

Hi Tanel,我知道,我在找,谢谢。 –