Ruby on rails “奇怪”;ArgumentError:密钥不能为空";关于aws S3
我有一个rails应用程序,允许用户直接上传与帖子相关的图像到S3,然后运行图像处理“延迟”作业来调整大小。使用web浏览器时,一切正常,但最近我编写了一些数据库填充任务,但当我尝试保存图像及其相关模型时,此错误显示:Ruby on rails “奇怪”;ArgumentError:密钥不能为空";关于aws S3,ruby-on-rails,ruby-on-rails-4,amazon-s3,Ruby On Rails,Ruby On Rails 4,Amazon S3,我有一个rails应用程序,允许用户直接上传与帖子相关的图像到S3,然后运行图像处理“延迟”作业来调整大小。使用web浏览器时,一切正常,但最近我编写了一些数据库填充任务,但当我尝试保存图像及其相关模型时,此错误显示:ArgumentError:key可能不是空的。任何关于为什么会发生这种情况的想法都很好 populate.rake代码的片段: post = Post.new(user: user) ((rand*5).floor + 1).times do ## Here, yo
ArgumentError:key可能不是空的
。任何关于为什么会发生这种情况的想法都很好
populate.rake代码的片段:
post = Post.new(user: user)
((rand*5).floor + 1).times do
## Here, you will need to upload the file to S3, get the direct_upload_url then save it for img.direct_upload_url
# Upload to S3, then get the direct_upload_url
file=File.open(Dir.glob(File.join(Rails.root, 'sampleimages/posts', '*')).sample)
s3_obj = S3_BUCKET.objects["direct_uploads/#{Time.now.to_i}/#{File.basename(file)}"]
puts " Selected file: #{File.basename(file)}"
puts " --> Starting upload"
s3_obj.write(file)
#s3_obj.acl= :public_read
obj_url = ""
while obj_url.blank?
obj_url = s3_obj.url_for(:read)
sleep(3)
end
puts " --> Loop completed with obj_url = #{obj_url}"
img = post.images.build(direct_upload_url: obj_url.to_s)
# puts "url_for #{obj_url}"
puts "Image uploaded: #{s3_obj.key} URL: #{img.direct_upload_url}\n"
# The below code is used for local file storage
#img.image_file = File.open(Dir.glob(File.join(Rails.root, 'sampleimages/posts', '*')).sample)
end
post.save!
end
错误出现在post.save代码>
下面是Image.rb
:
## S3_direct_upload post processing!
before_create :set_upload_attributes
### setting the image_to_process of this image.
before_create :inc_images_to_process
after_create :queue_processing
def direct_upload_url=(escaped_url)
write_attribute(:direct_upload_url, (CGI.unescape(escaped_url) rescue nil))
end
# Determines if file requires post-processing (image resizing, etc)
# All files should be processable in my case, where only images can be stored.
def post_process_required?
%r{^(image|(x-)?application)/(bmp|gif|jpeg|jpg|pjpeg|png|x-png)$}.match(image_file_content_type).present?
end
# Final upload processing step
def self.transfer_and_cleanup(id)
begin
## This will raise exception, need to catch this.
image = Image.find_by_id(id)
## Check if the image still exists when this is running, if not, then just skip this and minus one from post
if image.nil? || image.processed
## Something's wrong, either the image is not present or the image is already processed
Delayed::Worker.logger.debug "ERROR: Image with id: #{id} Not Found. This file will still up on aws temp!"
## The file is not here anymore.
## Ask the post to recalculate how many images it actually has!
if image.present? && image.processed
direct_upload_url_data = DIRECT_UPLOAD_URL_FORMAT.match(image.direct_upload_url)
S3_BUCKET.objects[direct_upload_url_data[:path]].delete
end
else
## With this match, path and filename will be extracted.
direct_upload_url_data = DIRECT_UPLOAD_URL_FORMAT.match(image.direct_upload_url)
if image.post_process_required?
image.image_file = URI.parse(URI.escape(image.direct_upload_url))
else
# Somethings's wrong???!?!?!? It should be images!
paperclip_file_path = "images/uploads/#{id}/original/#{direct_upload_url_data[:filename]}"
S3_BUCKET.objects[paperclip_file_path].copy_from(direct_upload_url_data[:path])
end
image.processed = true
if image.save
## To unset the image_to_process field of its parent - the Post
if image.imageable.class.to_s == "Post"
# logger.debug "I am here!!!"
post = image.imageable
post.images_to_process -= 1
post.save!
end
Delayed::Worker.logger.debug "Image:#{id}:transfer_and_cleanup: It is now saved"
else
Delayed::Worker.logger.debug "Image:#{id}:transfer_and_cleanup: ERROR Occurs: #{image.errors.full_messages}"
end
### End of image.save
## Delete the temp file.
Delayed::Worker.logger.debug "Image:#{id}:transfer_and_cleanup: direct_upload_url: #{direct_upload_url} is going to deleted"
S3_BUCKET.objects[direct_upload_url_data[:path]].delete
end
## end of image.present? loop
end
end ## End of transfer_and_cleanup
# Set attachment attributes from the direct upload
# @note Retry logic handles S3 "eventual consistency" lag.
def set_upload_attributes
logger.debug "You are now in set_upload_attributes"
tries ||= 5
direct_upload_url_data = DIRECT_UPLOAD_URL_FORMAT.match(direct_upload_url)
direct_upload_head = S3_BUCKET.objects[direct_upload_url_data[:path]].head
self.image_file_file_name = direct_upload_url_data[:filename]
self.image_file_file_size = direct_upload_head.content_length
self.image_file_content_type = direct_upload_head.content_type
self.image_file_updated_at = direct_upload_head.last_modified
## Rescue the S3 Errors here
rescue AWS::S3::Errors::NoSuchKey => e
tries -= 1
if tries > 0
sleep(3)
retry
else
false
end
end
# Queue file processing
def queue_processing
Image.delay.transfer_and_cleanup(id)
Delayed::Worker.logger.debug "queue_processing: Image #{id} added in the queue. At "
end
def inc_images_to_process
# Increase the image required to process in Post.
if self.imageable.class.to_s == "Post"
post = self.imageable
post.inc_images_to_process
Delayed::Worker.logger.debug "inc_images_to_process: Post #{post.id} new images_to_process is now: #{post.images_to_process}"
end
end
错误消息如下:
rake aborted!
ArgumentError: key may not be blank
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:384:in `validate!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:390:in `validate_key!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:542:in `block (2 levels) in object_method'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:1563:in `block (2 levels) in <class:V20060301>'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:560:in `build_request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:491:in `block (3 levels) in client_request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/response.rb:175:in `call'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/response.rb:175:in `build_request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/response.rb:114:in `initialize'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:203:in `new'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:203:in `new_response'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:490:in `block (2 levels) in client_request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:391:in `log_client_request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:477:in `block in client_request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:373:in `return_or_raise'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:476:in `client_request'
(eval):3:in `head_object'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/s3_object.rb:296:in `head'
/Users/quindici/Documents/Career/QUIN CREATIVES/Local-say/Local-say-System/app/models/image.rb:134:in `set_upload_attributes'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:377:in `_run__4088547230130556858__create__callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:80:in `run_callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:303:in `create_record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/timestamp.rb:57:in `create_record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:466:in `create_or_update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:299:in `block in create_or_update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:383:in `_run__4088547230130556858__save__callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:80:in `run_callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:299:in `create_or_update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:106:in `save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/validations.rb:51:in `save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/attribute_methods/dirty.rb:32:in `save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:270:in `block (2 levels) in save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:200:in `transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:209:in `transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:323:in `with_transaction_returning_status'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:270:in `block in save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:281:in `rollback_active_record_state!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:269:in `save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:39:in `insert_record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/autosave_association.rb:348:in `block in save_collection_association'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/autosave_association.rb:339:in `each'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/autosave_association.rb:339:in `save_collection_association'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/autosave_association.rb:183:in `block in add_autosave_association_callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/autosave_association.rb:153:in `instance_eval'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/autosave_association.rb:153:in `block in define_non_cyclic_method'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:383:in `_run__690630312330398441__update__callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:80:in `run_callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:307:in `update_record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/timestamp.rb:70:in `update_record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:466:in `create_or_update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:299:in `block in create_or_update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:413:in `_run__690630312330398441__save__callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:80:in `run_callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:299:in `create_or_update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:128:in `save!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/validations.rb:57:in `save!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/attribute_methods/dirty.rb:41:in `save!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:275:in `block in save!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `block in transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:210:in `within_new_transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:209:in `transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:323:in `with_transaction_returning_status'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:275:in `save!'
/Users/quindici/Documents/Career-System/lib/tasks/populate.rake:139:in `block (4 levels) in <top (required)>'
/Users/quindici/Documents/Career-System/lib/tasks/populate.rake:56:in `times'
/Users/quindici/Documents/Career-System/lib/tasks/populate.rake:56:in `block (3 levels) in <top (required)>'
/Users/quindici/Documents/Career-System/lib/tasks/populate.rake:31:in `times'
/Users/quindici/Documents/Career-System/lib/tasks/populate.rake:31:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:db_populate
rake中止!
ArgumentError:密钥不能为空
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:384:in'validate!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:390:in'validate_key!'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:542:in`block(2层)in object_方法'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/client.rb:1563:in'block(2层)in'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:560:在“构建请求”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:491:在“客户端请求中的块(3个级别)”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/response.rb:175:in'call'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/response.rb:175:在“构建请求”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/response.rb:114:in'initialize'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:203:in'new'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:203:in“new_response”
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:490:in `客户端请求中的块(2级)'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:391:in'log\u client\u request'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:477:在“客户端请求中的块”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:373:in'return_或_raise'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/core/client.rb:476:in'client_request'
(eval):3:在“head_object”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/aws-sdk-v1-1.56.0/lib/aws/s3/s3_object.rb:296:in'head'
/Users/quindici/Documents/Career/QUIN CREATIVES/Local say/Local say System/app/models/image.rb:134:在“设置上传属性”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active\u-support/callbacks.rb:377:在“运行”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active\u support/callbacks.rb:80:in'run\u callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/callbacks.rb:303:in'create\u record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/timestamp.rb:57:in'create\u record'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/persistence.rb:466:在“创建或更新”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/callbacks.rb:299:in'block in create\u或\u update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active\u-support/callbacks.rb:383:在“运行”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activesupport-4.0.0/lib/active\u support/callbacks.rb:80:in'run\u callbacks'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/callbacks.rb:299:in'create\u或\u update'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/persistence.rb:106:in'save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/validations.rb:51:in'save'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/attribute\u methods/dirty.rb:32:在“保存”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:270:在“保存中的块(2个级别)”中
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/transactions.rb:326:in`block in with\u transaction\u returning\u status'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/connection\u adapters/abstract/database\u语句。rb:200:in'transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:209:in'transaction'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/transactions.rb:323:in`with\u transaction\u returning\u status'
/Users/quindici/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.0/lib/active\u record/transactions.rb:270: