1. Skip to navigation
  2. Skip to content

The ELC Community Blog

A knowledge exchange on Ruby on Rails and Agile Development


AWS/S3 may cause rake task failed

by Yuanyi Zhang on January 24, 2008

I got a weird problem recently, the project runs well with script/server, but when I run a rake task, a 'uninitialized constant ***' error appeared. After spending me about 1h, I finally detected the problem was caused by AWS/S3 gem.

There's a rake file named 'mysql.rake' in my project, it requires 'aws/s3'. So when i running a rake task, AWS/S3 will be loaded before environment.rb, and it will define String#underscore before ActiveSupport, because ActiveSupport use Module to extend String, so AWS/S3 version will be used, but it's outdated:

# AWS/S3 version
def underscore
  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
  downcase
end unless public_method_defined? :underscore

# ActiveSupport Version
def underscore(camel_cased_word)
  camel_cased_word.to_s.gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
    gsub(/([a-z\d])([A-Z])/,'\1_\2').
    tr("-", "_").
    downcase
end

You should notice the difference, if a plugin doesn't require all its lib files in init.rb and it uses name space (eg acts_as_paranoid), and you just have a rake task need AWS/S3, then you will have problems to run rake tasks. because Rails can't load necessary files for that plugin automatically with the outdated String#underscore.

The solutions are:

  • modify the weird plugin to require all lib files itself.
  • update AWS/S3 with the new version String#underscore

But if it's a large plugin, then solution#1 will require lots of time, It's what i encountered, so I chose the solution#2.

I've submit a patch to AWS/S3 ml, but before they merging it into the trunk, if you are unfortunately the man satisfying all above conditions, hope this post can save a little time for you.

Comments

Add a comment


home | services | Ruby on Rails Development | code | blog | company