Fix rails database collations

Today I discovered my Ruby on Rails development environment database migrated with the wrong character encoding. It was using the MySQL default encoding latin1.
I didn’t feel throwing my database away because it contains a lot of stuff.

I used the following snippet to convert all columns to utf8

    ActiveRecord::Base.connection.tables.each do |table|
      ActiveRecord::Base.connection.execute( "ALTER TABLE `#{table}` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci")
    end
Share

A copy of has been removed from the module tree but is still active

I’m working on a rails website that requires me to specify a class in an initializer.

config/initializers

spree.searcher_class = MySearcherClass

I’m currently developing this searcher class. Every time I change this class I get the following message:

A copy of MySearcherClass has been removed from the module tree but is still active

This sucks big time! Because I need to restart my rails application every time I change something.

My workaround for the moment is this:

spree.searcher_class = class.new do
    def new(*args,&block)
      return MySearcherClass.new( *args, &block )
    end
  end
end

I’m not very keen on this, but it does the trick for now :)

Share

Ruby gsub gotcha

Today I struggled with a string replace that didn’t do what I expected it to do.

Consider the following code:

"xyz".gsub("y","a\\'b")
=> "xazbz"

Because gsub can be used with a regular expression the replace value can use regular expression backrefs.

I assumed (assumption is the mother of all fuckups) when using a plain string as search term, (which cannot result in back refs) it didn’t use backrefs..
Well I was wrong..

A solution is to use the block-variant:

"xyz".gsub("y") { "a\\'b" }
=> "xa\\'bz"

I think the behavior of gsub is wrong…
When you don’t have a regular expression you cannot have backrefs and you can have a dumb string replace…. What’s your opinion about this?

Share

Bundler / Passenger strange deployment Issue

Today I tried to deploy our Ruby on Rails application. Environment: Passenger with Ruby on Rails 1.9.3 (via system-wide-rvm) on FreeBSD. Deployment via a simple capistrano script.

After a successful capistano deploy I get the following error when trying to view it in the browser:

Web application could not be started

Could not find rake-10.1.0 in any of the sources (Bundler::GemNotFound)
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/spec_set.rb:92:in `block in materialize'
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/spec_set.rb:85:in `map!'
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/spec_set.rb:85:in `materialize'
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/definition.rb:114:in `specs'
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/definition.rb:159:in `specs_for'
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/definition.rb:148:in `requested_specs'
  /usr/local/rvm/gems/ruby-1.9.3-p392@generalrails/gems/bundler-1.3.5/lib/bundler/environment.rb:18:in `requested_specs'

When I run rake –version in the selected rvm-environment it just exists.
After searching for while I found the following problem:

Passenger gave the following GEM home:

GEM_HOME = /var/usr/local/www/https_www.webpathy.eu/shared/bundle/ruby/1.9.1

When I look in the directory “shared/bundle/ruby” I see everyting is deployed in a directory named: 1.9. The 1.9.1 directory is completely empty!

That’s not going to work
WTF!

My quick work-around is the following:

ln -s 1.9 1.9.1

Now it’s running again…
Does anybody know why bundler first deploys it all in “bundle/ruby/1.9” and passenger tries to grab it from “bundle/ruby/1.9” ?!?!?

Share

Ruby on Rails Json Serialization – To Infinity and beyond!

Wel the title says it all :)

There’s a subtile, but very important difference between Ruby on Rails 3 and 4 with json serialization.

Rails 3

(1..10).as_json => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Rails 4

(1..10).as_json => "1..10"

I had a piece of Ruby code that modeled the business rules of the application like this:

 
{
  brackets: [
    { income: 0..19_645,               perc: 37 },
    { income: 19_646..55_991,          perc: 42 },
    { income: 55_992..Float::INFINITY, perc: 52 }
  ]
}

Try serializing this to the browser with to_json in Rails 3 and prepare for a long wait ;)

The workaround I used to this was creating an initalizer “/config/initializer/range_to_json_monkey_patch.rb”

#
# This initializer requires some explanation
# 
# In the ruby version installed (Rails 3.2.13)  the json encoding method works like this:
#   ActiveSupport::JSON::encode(1..10)  => [1,2,3,4,5,6,7,8,9,10]
#
# Doing this with a large range  is not nice!!
#
# Ruby on rails 4.0.0.1 works like this:
#   ActiveSupport::JSON::encode(1..10)  => "1..10"
#
# This initializer modifies the Range#as_json method so it works like rails 4
# this method first checks if this adjustment is required
#
if (1..4).as_json.kind_of?(Array)

  class Range
    def as_json( options=nil )
      self.to_s
    end
  end

end

Now the json-serialization of Ranges will behave like the one in Rails 4.

Share