“About five weeks ago”:http://twitter.com/hvirring/status/12035555530 I launched a new version of “scrum.dk”:http://scrum.dk/. The site was rebuilt from the ground up using several bits and pieces of technology that I had wanted to try out for some time:
* Refinery CMS
“Refinery CMS”:http://refinerycms.com/: There are currently three Rails based CMSs that I think are suitable for production use: Radiant, BrowserCMS and Refinery. “Radiant”:http://radiantcms.org/ is the grand-old man of Rails CMSs, but I never really fell in love with it. “BrowserCMS”:http://browsercms.org/ looks like a really solid CMS with loads of features, especially features you would expect to find in commercial “enterprise” offerings. I find the interface to be quite complex, to the point where I think it will require training end users in its use, but I am sure it has its uses on larger CMS implementations. Refinery CMS is a fairly new Ruby on Rails CMS, that comes with a nice and clean interface and has the most basic functionality built-in, like image and file-upload.
“ThemeForest”:http://themeforest.net/: They have some great HTML templates, and this is now the first place I go to to find a template for a new project. Themes cost around $10-20 and the fact they charge for them, means you won’t see them on thousands of other sites.
“Heroku”:http://heroku.com/: Probably the slickest Ruby cloud platform available today. Deployment basically comes down to pushing your code to a remote repository on Heroku. That’s it! Heroku is a fully managed platform, so you never see a shell prompt, and don’t need to worry about installing any part of the Ruby web stack.
Refinery, ThemeForest and Heroku turned out to be a really potent mixture. Refinery helped me get a few pages of content up really quick and allowed me to easily add some custom functionality. The ThemeForest template solved was it often the biggest obstacle for a design-challenged developer: Making the site look professional. Heroku made deployment the simplest thing in world. I could have deployed to an existing server of mine with minimal effort, but that would have left me with one more application to babysit. As long as you plan on deploying to Heroku from the beginning by using PostgreSQL for development, Amazon S3 for file storage and make sure any gems or plugins are compatible with Heroku, you should have no difficulties getting your application deployed to Heroku.
Problem: You need to use attachment_fu for uploads in Rails, and would like to store your uploads in an Amazon S3 EU bucket. Amazon updated their API long ago, when they made EU buckets available, but for some reason the defacto standard library for working with S3 from Ruby, AWS::S3, was never updated to support the new API. As a result, you still can’t use the original AWS::S3, if you prefer storing your uploads on Amazons servers in Europe.
Now, there are other libraries that support EU buckets, like RightAWS or S3, but the upload plugin you use (in this case attachment_fu) has to support it. Previously the solution would be to switch to a different upload plugin that used another library, like Paperclip, but last time I checked, Paperclip had replaced RightAWS with AWS::S3. You might also for some reason not be able to switch to a different upload plugin.
On a recent project I was using the excellent Refinery CMS, which comes integrated with attachment_fu. I figured the problem using S3 EU buckets had been long solved, but apparently not, so here is the solution I cooked up:
# Install sauberia’s fork of AWS::S3: http://github.com/sauberia/aws-s3 either as a gem or a plugin in your Rails project.
# Install the attachment_fu plugin (Refinery CMS already has this): http://github.com/technoweenie/attachment_fu
# Patch attachment_fu to generate URLs that work correctly with Amazon S3 EU buckets, by using the code shown below:
# save this as vendor/plugins/attachment_fu_hacks/init.rb require 'aws/s3' Technoweenie::AttachmentFu::Backends::S3Backend.module_eval do # Hacked to use new S3 addressing, which lets us use EU buckets. # Requires sauberia's fork of aws-3s: http://github.com/sauberia/aws-s3 # # All public objects are accessible via a GET request to the S3 servers. You can generate a # url for an object using the s3_url method. # # @photo.s3_url # # The resulting url is in the form: http(s)://:bucket_name.:server/:table_name/:id/:file where # the :server variable defaults to AWS::S3 URL::DEFAULT_HOST (s3.amazonaws.com) and can be # set using the configuration parameters in RAILS_ROOT/config/amazon_s3.yml. # # The optional thumbnail argument will output the thumbnail's filename (if any). def s3_url(thumbnail = nil) File.join(s3_protocol + bucket_name + '.' + s3_hostname + s3_port_string, full_filename(thumbnail)) end end
Disclaimer: I have only tested this with Rails 2.3.5.
Update November 08, 2010:
It seems that Amazon updated the S3 API sometime around the end of October 2010. To successfully upload you now have to use a region-specific endpoint. If you followed this guide, you need to add “server: s3-eu-west-1.amazonaws.com” to your config/amazon_s3.yml file.
See this post for further details: Issues using Amazon S3 European Buckets.