An Awful Rails Project
Recently I was asked to migrate an existing rails app from its hosting to Rackspace. I was told the code base for the project was not very ‘good’, and I was supposed to fix issues that stood in the way during the migration.
I’ve been involved in quite a few existing rails projects for the past two years. I have to say this project is by far the most tough one with so many bad practices. I’ll share a few here.
Incomplete database migrations
As soon as I got the git access, I cloned the project and did a rake db:migrate. This failed thanks to some gems missing problem. The project didn’t use config.gem so I had to install these gems manually. After that db:migrate went well. I started the app in development mode, visited several pages, found that the signup page was not working. The signup form referred to firstname, lastname etc of the User model, it looked like these columns didn’t exist in the database.
I checked other models and found that the migration files only had less than half the schema for the database. Apparently the developer(s) stopped using rails’ database migrations at a certain point. I’m afraid they’ve altered the database schema directly from mysql. (I have to admit I did this one time last year, the project I was working on was hosted on a shared hosting without ssh access, the only way to change the database structure was to do it in PhpMyAdmin.)
Solution for this problem: got their current database dump, generated a schema from the dump using rake db:schema:dump.
None view templates under app/views
When I tried to start the app in production mode, I got this error:
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/erb.rb:469:in `scan': undefined method `empty?' for nil:NilClass (NoMethodError)
This didn’t happen under development mode. The error message indicated it had something to do with ERB. A quick check on views folders lead to the source of this problem. There were some jpeg image files under one of the views folder, and there was a file named semantic.cache under every folder (I guess this was generated by the IDE or editor, the developer just checked them into the code base)!
Solution for this problem: moved image files to public/images, removed all semantic.cache files.
Having a model called Spec!
This also prevented the app from running in production mode. The app had a model named Spec. The project installed the rspec and rspec-rails plugins. There seemed to be a name conflicts. Luckily (or unfortunately) the project didn’t have any rspec tests.
Solution for this problem: removed rspec and rspec-rails plugins. The Spec model was referred across the whole app I didn’t want to rename it.
Running the live app in development mode
At this point I was so surprised how their app was running on the current hosting. I doubted it wasn’t running in production mode at all. Then in the deploy.rb (did the capistrano deploy script really work?) file I saw this:
desc "Stop the sphinx server"
task :stop_sphinx, :roles => :app do
run "cd #{current_path} && RAILS_ENV=development rake thinking_sphinx:stop"
end
Oops, the live app was running in development mode!
Solution for this problem: had to fix some other issues to make the app run in production mode :-(
Update (May 19, 2009)
Hard-coded ImagicMagick path
What is this!!!???
def convert
if ENV["OS"] =~ /Windows/
"C:\\Program Files\\ImageMagick-6.3.1-Q16\\convert"
else
"/usr/bin/convert"
end
end
It simply doesn’t respect the fact that I have a Mac port version of ImageMagick which is under /opt/local/bin. The new hosting has it under /usr/local/bin. Wow!
Solution for this problem: if the app really needs to specify the ImageMagick path, have it in a config file and load it on start.
AR model’s initialize method not calling super
The project has one ActiveRecord model, the model has an initialize method:
class Transformer < ActiveRecord::Base def initialize(arg1) # do some great job end end
When creating a new object of this model, it gave a nil.has_key? error:
bumblebee = Transformer.new(sam)
NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.has_key?
This is caused by not calling super in the initialize method. Solution for this problem: add a call to super() in the initialize method.