coderrr

September 14, 2007

Incompatibility between Rails 1.1.6 and Ruby 1.8.6

Filed under: bug, rails, ruby — Tags: , , — coderrr @ 3:25 pm

After upgrading to Ruby 1.8.6 I discovered a problem with my Rails app (which is still using 1.1.6). Ruby 1.8.6 introduced a changed to the Digest classes. Previously you could use them like:

Digest::SHA1.new("string").digest

This is the way the mysql adapter works in ActiveRecord 1.14.4 (Rails 1.1.6). This no longer valid and will give you this error:

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/vendor/mysql.rb:551:in `initialize': wrong number of arguments (1 for 0) (ArgumentError)
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/vendor/mysql.rb:551:in `new'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/vendor/mysql.rb:551:in `scramble41'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/vendor/mysql.rb:141:in `real_connect'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:330:in `connect'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:87:in `initialize'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:36:in `new'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:36:in `mysql_connection'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract/connection_specification.rb:251:in `send'

The new Digest constructor takes no parameters. The correct way to use the Digest classes now is:

Digest::SHA1.digest("string")

So what’s the solution? Don’t upgrade to Ruby 1.8.6 until you upgrade to Rails 1.2.x (in which they changed the mysql adapter to use the new syntax). Or, modify the adapter yourself :

ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/vendor/mysql.rb:552-554

=begin
s1 = Digest::SHA1.new(password).digest
s2 = Digest::SHA1.new(s1).digest
x = Digest::SHA1.new(message + s2).digest
=end

s1 = Digest::SHA1.digest(password)
s2 = Digest::SHA1.digest(s1)
x = Digest::SHA1.digest(message + s2

That’s what I ended up doing.

Alternatively you fix it by putting this little piece of metaprogramming fun somewhere in your environment.rb:

class << Digest::SHA1
  class DigestProxy
    def initialize(content)
      @content = content
    end

    def method_missing(method, *args)
      Digest::SHA1.send(method, @content)
    end
  end

  alias_method :original_new, :new
  def new(*args)
    return original_new  if args.empty?

    DigestProxy.new(args.first)
  end
end

9 Comments »

  1. Thank you! This fixed our website that our hosting company did an unannounced upgrade to over the weekend!

    Comment by Matt — October 22, 2007 @ 4:56 pm

  2. You made my day! :)

    Comment by Stephan Kaag — November 1, 2007 @ 12:47 pm

  3. Thanks for that I was scratching my head on why one of my old sites stopped working on my dev box!

    Comment by Luke — November 28, 2007 @ 8:51 pm

  4. Thanks a lot – the “environment.rb” workaround worked like a charm…

    For some reson I kept getting syntax errors when I tried to use your code in the mysql.rb (unexpected =)

    Thanks anyway
    jim

    Comment by jimbo — April 13, 2008 @ 12:40 pm

  5. i have a feeling the syntax errors might have been because you had whitespace before the =begin and =end block comment lines.

    ruby will give a syntax error if there is any whitespace before =begin or =end must

    Comment by coderrr — April 14, 2008 @ 4:19 am

  6. Hey thanks buddy, But still i have a query whenever i am committing a code that time i have to remove this patch .. right?

    Comment by Abhishek Shukla — April 15, 2008 @ 9:59 am

  7. Thank you!

    Comment by Larry — August 7, 2008 @ 1:37 am

  8. [...] Incompatibility between Rails 1.1.6 and Ruby 1.8.6 – I’m sorry to say that I just needed to deploy this fix. I’m a full-time Rails developer and contributor, available for long- or short-term consulting, with solid experience in working as part of a distributed team. If you’d like to hire me, drop me a line. Links [...]

    Pingback by Double Shot #310 « A Fresh Cup — October 10, 2008 @ 10:35 am

  9. BRILLIANT. Thank you. Just spent the best part of a day scratching my head over this.

    Thanks

    Consider yourself BOOKMARKED!

    Comment by Pete — December 15, 2008 @ 4:34 pm


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.