24 5 / 2012

We recently started testing Capistrano again for deployment of our Rails app. One of the first things I set out to find was a way to use Capistrano without the versioned folder structure, since Git is in control of all our versioning.

I found this great article about how achieve a Git-based Capistrano strategy, where he references an older blog post on the Git that describes the speed benefits, and the added advantages of splitting up your deploy.rb file into numerous smaller files.

I was able to get all that up and working just fine, with a few minor changes to be able to use the provided Bundler and asset pipeline Capistrano tasks to install my required gems, and precompile assets. The first thing I noticed, however, was how frustrating it was to precompile assets every time I ran my deploy task. There had to be a better way!

Well, I’m proud to say I figured something out that I think will work well. We’ll see over time, as I try it in production.

My solution relies on checking the modified date of all non Git files nested under app/assets and finding those which have been modified in the last N minutes. If that list is empty it skips the asset precompiling by removing the :after callback that triggers it.

As you can see, I have created a few asset tasks that I place in an deploy/assets.rb file, which is included by my Capfile. The two tasks are described below.

determine_modified_assets: Sets the variable updated_assets to be an array of all assets that have been updated in the last N minutes. The amount of minutes is defined above by the max_asset_age variable I have set.

conditionally_precompile: Tests the updated_assets variable to see if any assets were updated. If not, it removes the :after callback that runs deploy:assets:precompile.

I also set an after chain that hooks into deploy:finalize_update, which runs well before the deploy:update_code task that the asset precompile task runs after by default. This gives us time to unset the callback.

07 3 / 2012

If you are anything like me you understand that sometimes there are things you want to do a certain way, simply because you want to understand how to accomplish the task in a specific manner. I came across one of those instances today while trying to convert an old SQL-laden ActiveRecord method to a new Rails 3 ActiveRecord::Relation chain.

I wanted to know if there was a way to do a GROUP BY in MySQL on a DATE() converted value of a column without having to write the raw SQL statement. Before I show anything I want to acknowledge that I do understand that it would be cleaner to read, and easier to accomplish, if I had just written the SQL into the group() portion of the chain. My concern was finding a way to achieve this same effect using Arel, just incase you wanted to write database-agnostic code.

Now let’s suppose you wanted to grab the DATE() conversion of a DATETIME column, and that you already understand Arel and are using it to start building a join…

You can see we aren’t using SQL strings to build our join, so why should we have to in order to get our date conversion, or other undefined Arel methods? As it turns out, we don’t! Arel has a little class called NamedFunction that will give us exactly what we want…

You can see by my printing of the generated SQL when running .to_sql that we were able to build the same result without writing any raw SQL, short of the function name. The second argument passed to a new NamedFunction instance needs to be an array, which you can utilize if your SQL function requires multiple arguments.

With a little knowledge of how Arel builds the SQL strings you can even get a bit tricky with Arel::Attributes::Attribute objects and start using Arel to do things such as build a CAST() function…

Anyways, mess around with it. Even if you don’t deem it clean enough to be of use, at least you know to do it.

06 12 / 2011

02 12 / 2011

29 11 / 2011

25 11 / 2011

24 11 / 2011

28 10 / 2011

Sunrise

Sunrise

25 10 / 2011

Cafe

Cafe

23 10 / 2011

Road Trippin’

Road Trippin’

12 10 / 2011

DC*B

DC*B

21 9 / 2011

14 9 / 2011

09 9 / 2011

Sunbreak

Sunbreak

11 8 / 2011

Morning Group

Morning Group