PaperTrail + Sinatra strangeness
This is one of those Google-baiting posts that coders write for other coders in hopes of saving them hours of frustration. It's unlikely to be of interest to anybody else.
As we moved Profitably to Rails 3, we were having a strange problem upgrading PaperTrail. PaperTrail needs to be upgraded to 2.x for Rails 3, but as soon as we upgraded it, we couldn't even load the environment. The traceback we'd get looked like this:
$ ./script/rails runner "puts 'hello world'" /Users/francis/.gem/gems/activerecord-3.0.7/lib/active_record/named_scope.rb:132:in `valid_scope_name?': private method `warn' called for nil:NilClass (NoMethodError) from /Users/francis/.gem/gems/activerecord-3.0.7/lib/active_record/named_scope.rb:102:in `scope' from /Users/francis/.gem/gems/paper_trail-2.5.0/lib/paper_trail/version.rb:18 from /Users/francis/.gem/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in `require' from /Users/francis/.gem/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in `require' from /Users/francis/.gem/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:225:in `load_dependency' from /Users/francis/.gem/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:596:in `new_constants_in' from /Users/francis/.gem/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:225:in `load_dependency' from /Users/francis/.gem/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in `require' from /Users/francis/.gem/gems/paper_trail-2.5.0/lib/paper_trail.rb:7 from /Users/francis/.gem/gems/bundler-1.0.15/lib/bundler/runtime.rb:68:in `require' ...
If you're seeing this error, you may also have Sinatra in your Rails app for some strange reason (our strange reason is explained below). If that's the case, then the fix is to tweak your Gemfile with a
gem 'sinatra', '1.0', :require => 'sinatra/base'
If the fix is simple, the actual cause was pretty gnarly. PaperTrail comes packaged with an ActiveRecord model called Version, with a scope called
after. In ActiveRecord, the scope method will log a line if it's overwriting an existing method, though in this case
ActiveRecord.logger isn't even defined yet, so you get a traceback from trying to call
Sinatra, by default, writes a bunch of global methods like
post, etc, which makes perfect sense if you're writing a quick Sinatra app, so you can do stuff like:
get '/hi' do "Hello World!" end
Only problem being, in our case, that it also defines
after, which is then defined on every Ruby object, including PaperTrail's Version class. (Yes, defining a method globally will define it on every single Ruby object, which is why you don't want to do it that often.)
Anyway, you can configure Sinatra not to create those methods globally, which is what the above Gemfile change will get you.