iprog.com

Errors when precompiling assets in Rails 4.0

Rails 4 now always loads initializers and the database configuration before precompiling assets. Depending on your deployment environment, this may cause errors.

For example, not finding database.yml:

Could not load database configuration. No such file - /apps/some_app/releases/20130703220638/config/database.yml

In Rails 3, this was solved with:

1config.assets.initialize_on_precompile = false

However, this configuration option no longer exists in Rails 4. One workaround is to pass a dummy database init string to rake assets:precompile:

1DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname

Be sure to replace postgresql with your database adapter name if using something other than Postgres.

A complete example:

1bundle exec rake RAILS_ENV=production DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname assets:precompile

With Capistrano’s assets handling, you can just set :asset_env:

1set :asset_env, "RAILS_GROUPS=assets DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname"
5 comments

Preparing for an upgrade to Rails 4.0

There are a number of steps you can take to prepare an app for an eventual upgrade to Rails 4.0. Taking these steps now will simplify the upgrade later.

1. Upgrade everything else possible

It seems simple, but upgrade everything else possible first. This means ensuring you’re on Ruby 1.9.3 or 2.0.

Update as many other gems as possible too.

bundle outdated may be a helpful tool. Just know that it lists all potential upgrades, not just upgrades that are compatible with your existing Rails 3.2 stack. (For example, it will list the Rails 4 gems.)

2. Move to strong_parameters

Rails 4 ditches attr_accessible/attr_protected in the models and replaces them with controller-based handling. This has the benefit of letting each controller handle things individually. The new format looks something like this:

1params.require(:user).permit(:username, :password)

This new way of handling the params hash is available as a standalone gem for Rails 3.2: strong_parameters.

It’s a fairly easy change to make ahead of time. After using the new style, I happen to prefer it over the old way – you might too.

3. If you use ActiveRecord, change all scopes to lambdas.

Old style:

1scope :is_active, where(active: true)

Becomes:

1scope :is_active, ->{ where(active: true) }

Or if you’re more comfortable with the older Ruby syntax:

1scope :is_active, lambda{ where(active: true) }

Anything that was already a lambda stays as is.

4. Tidy up RegExp’s

Technically speaking, anchoring to the beginning of a string in a Regexp should use \A not ^. Likewise, anchoring to the end should use \z instead of $.

If you’re dealing with input that’s known to be at least somewhat sane, ^ and $ are fine – and visually a little cleaner.

However, ^ and $ only anchor to the beginning of a line within a string. When dealing with user-provided input, this is not good (nor sufficient).

Rails 4 now enforces better behavior for all validation strings so as to avoid careless mistakes.

So this:

1validates_format_of :alphabet, with: /^abc.*xyz$/

Becomes:

1validates_format_of :alphabet, with: /\Aabc.*xyz\z/

It may be worthwhile to search your entire code base for /^ and $/ (not just app/models/*.rb) as an incorrect RegExp could potentially have security implications for your app.

5. Update routes.rb

Rails 4 places new restrictions on the match method in routes.rb.

Search routes.rb for match. For each occurance, if it only needs to allow a single HTTP verb, just change it to get, post, put, or delete.

If it needs to allow multiple verbs, then explicitly list them using :via:

1match '/contact', via: [:get, :post]

6. Ensure your test suite passes

If you have tests, make sure they’re not broken before you even start.

If there are a few holes in your test suite, now might be a good time to plug them.

If you don’t have a test suite, ideally you’d consider writing one now. But that’s pretty unrealistic, so just prepare to spend some extra time exercising the various parts of your app when you do the Rails 4 upgrade. If you have any particularly fragile parts of your app, it might be worth considering writing a few tests for those areas.

0 comments

New and shiny site design

Once again it has become time to refresh the site design. Looking back, it appears the last site refresh was in July of 2007—I’m not sure if 5 years on the same design demonstrates longevity and consistency, or if it just means I’m horribly overdue.

Regardless, now everything is nice and shiny. One of the goals of the new design was to do my best to leverage HTML5 and CSS3, including new HTML5 tags and use of many of the newer CSS features. As a consequence, the only image file is the background. Everything else is CSS effects along with a couple CSS fonts.

I also used the refresh as an excuse to experiment with responsive design. I haven’t had a chance to test a wide array of small-screen devices yet, but on the ones I have access to (various iDevices), the site is usable. I’d love to hear your experience, good or bad, on any kind of smaller-screen device.

Other changes include numerous updates to the software stack (Rails 3.2, etc.), better syntax highlighting (now with line numbers!), and improved (in theory) spam filtering.

0 comments

Catching up

It’s clearly time that I catch up with the world around me. It’s curious how much can pass you by while you’re consumed with other priorities. Now that some of those have passed, I’m rediscovering several things that got pushed aside.

Among them is hopefully writing at least a little more often here. Apparently, that won’t be a difficult bar to jump over—it’s been 2 1/2 years since my last post. Ack!

Apart from writing here, the process of catching up looks like it will include a bunch of software upgrades (Rails 3 a part of that), a new design for here, and migrating a bunch of stuff to git.

Stay tuned.

0 comments

Faster alternatives to ActiveRecord::Base.to_xml (Rails Performance Series)

This is part 5 of my ongoing series on Ruby on Rails performance. Today’s topic is a bit more complicated that some of the previous parts.

I’m going to explore an alternative to using the method 1ActiveRecord::Base.to_xml.

Before I get into that, I probably should explain why. After all, 1ActiveRecord::Base.to_xml is really easy to use. The alternative I’m going to demonstrate isn’t very easy to use.

The problem is that 1ActiveRecord::Base.to_xml can be really slow—even after making the optimizations I’ve explored in the previous parts to this series. For fairly simple AR objects, this won’t be a problem. However, when you have a deep object hierarchy and need substantial portions of it to be included in the XML response, it becomes a problem.

One instance where I encountered this was a nested has_many tree. That is, the object tree looks something like this:

The XML output is often 100k or more, and representing a few dozen or more total objects.

Read more...

0 comments