Archive for the 'Ruby on Rails' Category

Ruby thinks (19.99 * 100).to_i = 1998

Thursday, March 26th, 2009 By: Daniel
>> (19.99 * 100).to_i
=> 1998
>> (9.99 * 100).to_i
=> 999

Someone please tell me what’s up with that!

In the meantime:

>> (19.99 * 100).to_s.to_i
=> 1999

A Couple Rails Find Gotchas

Tuesday, March 3rd, 2009 By: Daniel

We ran into a few little gotchas with ActiveRecord’s find method when upgrading from Rails 2.1.1 to 2.2.2. The solutions are pretty trivial, so the main lesson here is to test your code so things like this get caught by your test suite and not the client.

Read the rest of this entry »

Vim as a Ruby on Rails IDE

Monday, December 29th, 2008 By: Daniel

In the words of Tim Pope “TextMate may be the latest craze for developing Ruby on Rails applications, but Vim is forever”

Here’s how I use vim (and gnome-terminal) to program in Rails on Ubuntu.

I have a ruby script that opens two gnome-terminals each with 9 tabs each. That may seem like a lot, but each one is assigned a specific purpose and by now my fingers know just where to go depending on the task at hand. For example, models, views and controllers each get their own tab. So if I need to edit a model my fingers will do an vim model_name.rb (or :e model_name.rb if I’m already in vim). And of course bash aliases and tab_completion minimizes the actual number of keystrokes required. In the same way, I know exactly where to go to watch the log, play in the console, use the SCM or anything else.

My Vim Rails IDE

So that’s what it actually looks like. Notice how I have Gmail in the background so I can know immediately when I get a new email or IM (and ignore it at my leisure). Not shown is a separate Firefox window running on my other monitor so that I can see both the code and the running application at the same time.

Now, I have some doubts as to how well my solution would work for other people as it requires a bit of discipline to make sure everything has a place and to train yourself to always do things in the right place. It seems most people prefer to have only a few windows (or tabs or buffers or whatever) open and use some sort of fuzzy finder or file explorer to find the file they want to work on next. But that’s what I love about vim. I can come up with a custom workflow that works for me instead of conforming to the whims of some dictatorial IDE. True, the learning curve was quite steep at first, and I still occasionally invest some of my time in learning how to use additional features and customizations, but now contemplating using another text editor is like going back to riding tricycles after learning to fly jet planes.

Here’s the current version of the ruby script in case anyone’s interested. I call it zvim_rails_ide so I can use it with a quick zv<tab>.

#!/usr/bin/env ruby
 
if ARGV.size.zero?
  puts "Usage: #{File.basename($0)} name_of_project"
  exit
end
 
RAILS_ROOT = File.join(Dir.pwd, ARGV[0])
RAILS_ROOT << '/' unless RAILS_ROOT[0] =~ %r{/$}
 
unless File.exists?(RAILS_ROOT)
  puts "#{RAILS_ROOT}: No such file or directory"
  exit
end
 
ls = "ls --color"
scm = File.exists?('.git') ? 'git status' : 'svn status'
test_dir = File.exists?("#{RAILS_ROOT}spec") ? 'spec' : 'test'
 
[
  {
    :geometry => "140x38+90+270",
    :tabs => [
      {:path => "app/models", :command => ls},
      {:path => "app/views", :command => ls},
      {:path => "app/controllers", :command => ls},
      {:path => "app/helpers", :command => ls},
      {:path => "public", :command => ls},
      {:path => "vendor", :command => ls},
      {:path => test_dir, :command => ls},
      {:path => test_dir, :command => ls},
      {:path => "", :command => ls}
    ]
  },
  {
    :geometry => "141x32+185+110",
    :tabs => [
      {:path => "", :command => scm},
      {:path => "", :command => ls},
      {:path => "lib", :command => ls},
      {:path => "", :command => "ruby script/console"},
      {:path => "", :command => ls},
      {:path => "config/locales", :command => ls},
      {:path => "", :command => ls},
      {:path => "", :command => ls},
      {:path => "", :command => ls}
    ]
  }
].each do |window|
  tabs = window[:tabs].map {|tab| "--tab-with-profile=DEFAULT --working-directory='#{RAILS_ROOT}#{tab[:path]}' -e \"bash -c '#{tab[:command]}; bash'\""}.join(' ')
  system "gnome-terminal --geometry #{window[:geometry]} #{tabs}"
end

Using Rails’ New I18n Support in Real Life: Part the Fourth

Tuesday, December 16th, 2008 By: Daniel

So after tediously going through your entire site and extracting all displayed strings to a separate translation file, how do you know you didn’t miss something somewhere? My solution was to create a quick rake task that machine translates my English yaml file to something else. A quick sudo aptitude install bsdgames and I had pig latin at my fingertips. So I switched to that and browsed through the site and looked for anything that hadn’t changed. And I found quite a bit of stuff that I had missed.

# lib/tasks/pig.rake
desc "Creates a config/locales/pig-US.yml from config/locales/en-US.yml"
task :pig => :environment do
  DEFAULT_LOCALE = 'en-US'
  File.open(File.join(RAILS_ROOT, 'config', 'locales', 'pig-US.yml'), "w") do |fout|
    File.readlines(File.join(RAILS_ROOT, 'config', 'locales', "#{DEFAULT_LOCALE}.yml")).each do |line|
      unless line =~ /"/
        fout.puts line.sub(DEFAULT_LOCALE, 'pig-US')
      else
        key, *translation = line.split(':')
        translation = translation.join(':')
        translation.split(/(".*?")/).each do |quote|
          if quote =~ /"/
            quote.gsub!('"', '')
            string = quote.split(/(\{\{.*?\}\})/).map do |s|
              (s =~ /\{\{/) ? s : `echo "#{s.gsub('$', '\$')}" | pig`.chomp
            end
            translation.sub!(quote, string.join)
          end
        end
        fout.puts "#{key}:#{translation}"
      end
    end
  end
end

P.S. Note to anyone that actually tries to use this: This is just a quick and dirty script and will probably require some modification to work in your situation. In particular it requires all the strings you want translated to be within double quotes.