A Whole World of Difference: Phusion Passenger Apache to Nginx, Ruby Enterprise Edition 1.8.6 to 1.8.7

Yesterday we have launched the new design of Creattica. It runs well during the testing and staging phase, unfortunately the server quickly became overloaded and unresponsive after the relaunch was made public.

The site was running fine with its old design, but because the new design has many added features such as search filters, followers and more, system resources were very quickly drained.

After some optimisation of the database (which itself has increased the site performance by up to 300%+), queries as well as upgrading Ruby Enterprise Edition from 1.8.6 to 1.8.7 and switching from using Apache + Passenger to Nginx + Passenger, the site runs so much smoother.

Don’t believe me? Take a look at these screenshots below.

Switching from REE 1.8.7 to Ruby 1.9.1 did not yield any significant result though.

[Rails] Use App_Config For Your Application Specific Configuration

A simple Google search will reveal that there are a number of different App_Config plugins for Rails. After comparing them side by side, I have decided to use the one by Christopher J. Bottaro.

It features:

  • simple YAML config files
  • config files support ERB
  • config files support inheritance
  • access config information via convenient object member notation

I just fixed a bug last night (which was pulled in to the main repository) where it could throw errors when used as a Rails plugin (i.e. via rails plugin install).

Make sure you go read the instructions on how to use this handy plugin.

[Rails Tip] Model Attributes Not Updating? `reset_column_information` To the Rescue!

So you were wondering why some of your model attributes weren’t updating properly? Well, it is perhaps because the db schema has changed but the changed schema has not been passed onto ActiveRecord, as is often the case in DB migration.

Taken from the ActiveRecord documentation:

Resets all the cached information about columns, which will cause them to be reloaded on the next request.

The most common usage pattern for this method is probably in a migration, when just after creating a table you want to populate it with some default values, eg:

  class CreateJobLevels < ActiveRecord::Migration
    def self.up
      create_table :job_levels do |t|
        t.integer :id
        t.string :name

        t.timestamps
      end

      JobLevel.reset_column_information
      %w{assistant executive manager director}.each do |type|
        JobLevel.create(:name => type)
      end
    end

    def self.down
      drop_table :job_levels
    end
  end

[Rails Tip] DataMapper M:M Association Bug and Workaround

It was confirmed that DataMapper is incorrectly setting table names in SQL JOINs.

So for instance, the following code would generate an SQL error:

type.jobs.all(:"country.name".like => "%#{params[:location]}%")

There is a workaround, however the workaround requires manual looping of the dataset thus produces N+1 queries.

type.jobs.all.reject do |job|
  ! job.country.name.downcase.include?(params[:location].downcase)
end

But at least it works. ;)

[Rails Tip] Run Specs Faster!

If you are using rake spec to run the specs. Try using spec spec instead! It avoids doing some preliminary tasks and therefore is quicker to execute.

You can verify the difference using Unix’s time command, i.e. time spec spec and time rake spec.

[Rails] Run Queued Tasks Using ‘delayed_job’, Now With Intervals!

If you don’t already know, ‘delayed_job’ is a database based asynchronously priority queue system extracted from Shopify.

I was seeking for a lightweight, easy to use solution for queueing tasks, ‘delayed_job’ fits the bill almost perfectly. ;)

One thing we needed to do for a Rails 2 project at Envato, was to queue the tasks and to run them one after another, at a set interval. ‘delayed_job’ unfortunately doesn’t come with this feature.

So, instead of searching for more complicated solutions or reinventing the wheels, I made a couple of commits to my fork to add this functionality as well as to fix some rails 3 compatibility issues.

Now you can simply add the following line to your config/initializers/delayed_job_config.rb file to have the tasks run at 1 minute interval.

Delayed::Worker.run_interval = 60

A pull request has been issued, hopefully it’ll come as a standard feature soon. :)

[Rails] Use HAML templates with Devise

If you are a Rails developers, chances are you have heard of, or are using either Devise or HAML in your projects.

And if you’re like me who uses both, then surely you’d wish these two worked together, i.e. generate devise views in HAML.

Today is your lucky day! I’ve just committed some changes that enable you to do so! The changes are already merged back to the primary repository.

In order to generate HAML views instead of ERb views, simply do:

rails g devise_views -t=haml

You can use the master branch of Devise, i.e. in your Gemfile:

gem "devise", :git => "git://github.com/plataformatec/devise.git"

You will also need the edge version of HAML, as the stable versions do not parse ruby code correctly.