Switching between Rails 2 and Rails 3 on Mac OS X or Ubuntu with RVM

I’m migrating AdGrok to Rails 3 this weekend–what with the new ActiveRecord query functionality, and MongoMapper, and all our gems migrating to Rails 3, it seems like it’s time.

The Railscast (and ASCIIcast) is great, but a couple steps are now outdated. There also aren’t any instructions on how to switch between rails 2 and rails 3 gracefully.

Continue reading

HOWTO: Fix Ruby on Rails 2.3.x textarea Value Truncation

Turns out that Rails versions 2.3.6 through 2.3.8 have a pretty horrid parameter-parsing bug, and I’m surprised there hasn’t been more hoopla about it.

If you have a textarea form that someone types a quote character into, the value you get back from params[:key] is truncated at the point of the quote.

Monkey patching to the rescue!

I decided to add a new raw_params method to ActiveRecord::Request, rather than fixing the bug and dealing with more potential side-effects, assuming this mess will be fixed in Rails 3. If it isn’t, we should fix ActionController::Base.param_parsers[:url_encoded_form] to return the properly-parsed parameters from the raw_post.

In your rails application, create config/initializers/request.rb, with the following contents:

Continue reading

Simple 301 or 302 redirects with Apache or PHP

It behooves you to make sure you’ve only got one URL that serves a given piece of content–so says google. But what if you’ve got a bunch of domains that go to your page?

For this blog, for example, matthew.mceachen.org, and mrm.mceachen.org all go to the same place. That was done with an apache redirect in /etc/apache2/sites-enabled/matthew:

Continue reading

HOWTO: Configure an Amazon RDS instance to use UTF-8

RDS has been working out pretty well for AdGrok — it’s a one-click MySQL 5.1 instance that seems pretty promising:

  • Automatic replication and failover to another deployment zone (colo)
  • Easy to set up firewall configuration
  • Easy to scale up (but not down) for CPU and disk space

If you’re just starting out, it’s a whole lot simpler than, say, a DRBD/Heartbeat/MySQL configuration running on EC2 instances.

There’s just one catch. It doesn’t use UTF-8 encoding by default, it uses latin1_swedish. If you’re going to do business outside the US, utf8 is a must.

The second catch — the Amazon web UI for managing RDS “parameter groups” is read-only. If you know the magick incantations, though, it’s not that bad. Here’s how to make it all go:

Continue reading

HOWTO: Mount your USB hard drives at boot time on Ubuntu

I’ve got a number of external USB hard drives connected to my ubuntu server that need to mount to a predictable directory.

When you log into Gnome, the desktop environment does it’s nifty thing and mounts any drive you’ve got plugged in — but if the box reboots, the drives won’t be mounted until the next person logs into the computer.

I needed something that happens at boot time to do this task.

Continue reading

Dialed-in Rails script/console with pretty printing and history

Edit (as root) your /etc/irbrc:

# Some default enhancements/settings for IRB, based on
# http://wiki.rubygarden.org/Ruby/page/show/Irb/TipsAndTricks
 
unless defined? ETC_IRBRC_LOADED
 
  # Require RubyGems by default.
  require 'rubygems'
 
  begin
    require "ap"
    IRB::Irb.class_eval do
      def output_value
        ap @context.last_value
      end
    end
  rescue LoadError => e
    puts "ap gem not found.  Try typing 'gem install awesome_print' to get super-fancy output."
  end
 
  # Activate auto-completion.
  require 'irb/completion'
 
  # Use the simple prompt if possible.
  IRB.conf[:PROMPT_MODE] = :SIMPLE if IRB.conf[:PROMPT_MODE] == :DEFAULT
 
  # Setup permanent history.
  HISTFILE = "~/.irb_history"
  MAXHISTSIZE = 100
  begin
    histfile = File::expand_path(HISTFILE)
    if File::exists?(histfile)
      lines = IO::readlines(histfile).collect { |line| line.chomp }
      puts "Read #{lines.nitems} saved history commands from '#{histfile}'." if $VERBOSE
      Readline::HISTORY.push(* lines)
    else
      puts "History file '#{histfile}' was empty or non-existant." if $VERBOSE
    end
    Kernel::at_exit do
      lines = Readline::HISTORY.to_a.reverse.uniq.reverse
      lines = lines[-MAXHISTSIZE, MAXHISTSIZE] if lines.nitems > MAXHISTSIZE
      puts "Saving #{lines.length} history lines to '#{histfile}'." if $VERBOSE
      File::open(histfile, File::WRONLY|File::CREAT|File::TRUNC) { |io| io.puts lines.join("\n") }
    end
  rescue => e
    puts "Error when configuring permanent history: #{e}" if $VERBOSE
  end
 
  ETC_IRBRC_LOADED=true
end

Thanks to Nick Sieger and Jared Haworth for sharing.

HOWTO enable the query log on MySQL on Mac OS X

Tailing the MySQL query log in real time can be a lifesaver for any developer, and it’s pretty easy to do.

1. Make the logfile

Create the logfile that the mysqld process will write to.

If you’re using MacPorts or the MySQL package, run this on the terminal:

sudo touch /var/log/mysql-query.log
sudo chown _mysql /var/log/mysql-query.log

If you’re using homebrew, MySQL will be running with your user id, so you’ll want to:

sudo touch /var/log/mysql-query.log
sudo chown `whoami` /var/log/mysql-query.log

2. Tell MySQL to write to the logfile

If you’ve installed MySQL 5.1.x from the Mac .pkg, you won’t have an /etc/my.cnf, but it just needs to have these two lines:

[mysqld]
log=/var/log/mysql-query.log

3. Restart mysqld

If you have the MySQL preference pane, open that, click stop, then start. (It turns out that when the preference pane is open, it pings the database every 2 seconds, so it can detect if the db is alive. If you mangle the my.cnf, you’ll find the start button seems to not respond to clicks.)

If you installed MySQL with homebrew or MacPorts, and installed a launchd script to start MySQL on startup, you can run mysqladmin shutdown and launchd will restart MySQL for you.

4. Finally: watch the query log

Run tail -f /var/log/mysql-query.log

Installing Phusion Passenger on Ruby 1.9.1, Nginx, & Ubuntu 10.04

I wrote this a while back, before I knew about RVM. The Ruby Version Manager has a bunch of features that makes it better than macports for ruby and gem installation. Read about it here.

Getting ruby 1.9.1 and nginx and passenger and ubuntu to all play nicely is fairly straightforward, but it’s not just “apt-get” and “gem install” lovin’.

Making ruby 1.9.1 the default ruby is OK. Follow these steps:

Continue reading