Ruby GetText will eval scripts containing ActiveRecord classes

Updated . Posted . Visible to the public.

When the Ruby parser module of Ruby-GetText Show archive.org snapshot comes across a file in one of its search directories (e.g. lib/scripts/) and finds out that you are defining ActiveRecord classes inside it, it evaluates the whole file. Here is how to avoid that.

What's happening?

Let's say you have the following script which is only run once, manually, via script/runner:

# lib/scripts/doomsday.rb
class User < ActiveRecord::Base; end
User.destroy_all

In that case we would define a User model solely for the purpose to have access to the users table via ActiveRecord, without being affected by the application's real User class.

Unfortunately GetText::ActiveRecordParser.target? tries to be smart when looking for model attributes to put into po files. If it encounters any declaration like ...

class User < ActiveRecord::Base

... it will claim that it can handle the class. Then, its parse method will evaluating the whole file to do so:

# from the Gem's lib/gettext_activerecord/parser.rb:
eval(open(file).read, TOPLEVEL_BINDING)

This means that the script will be executed every time you run the rake task to rebuild your po files.

Holy cow!

Fix 1: Cheat

Use the following hack to define classes inside your scripts and trick the gem:

eval <<RUBY
  class User < Active#{}Record::Base; end
RUBY
User.destroy_all

Ugly as hell, but works.

Fix 2: Blacklist

Another solution would be to exclude lib/scripts explicitly in your GetText rakefile:

paths = Dir.glob("{app,lib,assets}/**/*.{rb,erb,rjs}").reject do |filename|
  filename =~ %r{^lib/scripts}
end
GetText.update_pofiles('my_project', paths.sort, 'my fancy project')

Note that this means it will break for you again once files are added in a non-excluded path.

Arne Hartherz
Last edit
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2011-08-12 13:09)