Rails Carrierwave NoMethodError
Posted
技术标签:
【中文标题】Rails Carrierwave NoMethodError【英文标题】: 【发布时间】:2014-02-12 20:18:08 【问题描述】:我正在尝试在我的应用中实现 Jcrop 并不断收到以下错误:
NoMethodError in PeopleController#update
undefined method `body' for nil:NilClass
我正在使用 Rails 4.0.2、Ruby 2.0.0p0、Bootstrap 2.3.2、Jcrop 0.9.12、Rmagick 2.13.2
奇怪的是,如果我重新加载此人的页面,裁剪后的图片会保存到 S3 并显示在 UI 中。但是,每次我尝试裁剪图片时都会发生此错误。
这是我的人物模型。我已经用 ** 标记了生成错误时在浏览器中突出显示的行。
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'
有什么想法可以解决这个问题吗?
谢谢
【问题讨论】:
你能出示你的表格吗? 在某处调用对象的方法body
,而该对象是nil
。尝试找到它在哪里,可能是在布局中还是在更新视图中的其他地方?
嗨 Sergio,我到处搜索“body”,只找到有效的 和 引用。当我查看我的 development.log(我已经添加)时,我认为问题是由我在控制器中注释掉的一些行引起的(我现在正在显示)。我将它们注释掉是因为我有点菜鸟并且不认为它们是必要的,当我删除它们时,我遇到的问题得到了解决。因此,它似乎正在寻找“更新为 HTML”代码,但我已将其注释掉。我删除了它们,因为当它们在那里时,我得到了一个“AbstractController::DoubleRenderError in PeopleController#update”
你能显示完整的堆栈跟踪吗
【参考方案1】:
触发异常的实际代码在Carrierwave repository 中。
回溯查看where 它实际上被称为告诉它正在尝试缓存由于某种原因不存在的文件。调试的下一步将是实际确保您尝试重新裁剪的文件存在。我在想,因为您是在 after_update
hook 中执行此操作,所以您的文件可能在您需要的状态下不存在。
【讨论】:
当我注释掉我模型的那一行时,我没有收到任何错误(这很好)。但是,图像也不会被裁剪。嗯…… 我不能为你调试你的代码,因为我没有它不能运行它。我只能告诉你你应该在哪里寻找。 嗨,Tanel,我知道,我正在寻找。谢谢。以上是关于Rails Carrierwave NoMethodError的主要内容,如果未能解决你的问题,请参考以下文章
Rails 4,Carrierwave,jcrop,移动到 POST,而不是 UPDATE
rails4.2.8carrierwave+mini_magick+Jcrop,图片上传失败
Rails 4.2.6 + 多态 + Carrierwave 0.10 + 条件
rails + WebRTC 录音 + Carrierwave + 雾 + S3 + Ajax 错误