Imagine that you're nearing the end of a productive day. Just a little more work to do to finish a feature. Then, your customer calls about a problem. You form a few ideas about the cause as you listen to your customer describe the problem. You stash your changes for the nearly complete feature and don your bug-hunting hat.
To mimic the problem on your machine, you boot the Rails 2.3 application in production mode.
$ script/server production
Sure enough, the application doesn't properly update a record.
You fire up the console to inspect the record in question.
$ script/console production
Hmm. The record doesn't have the values that you just saw in the web browser. After a little more time exploring in the console and not seeing what you expect, you go directly to the database. Yes, it's the same thing underneath it all, but you're quite puzzled at this point.
$ script/dbconsole production
It's no surprise that what you see in
script/dbconsole is the same as in
We are running in production, right?
Then it hits you!
script/dbconsole may not be running in the same environment. You scroll back in your terminal and see that your local server is running in the development environment.
How'd you miss that? Inconsistent APIs among
script/dbconsole. Here's the output from running each of them with the
$ script/server --help Usage: server [options] -p, --port=port Runs Rails on the specified port. Default: 3000 -b, --binding=ip Binds Rails to the specified ip. Default: 0.0.0.0 -c, --config=file Use custom rackup configuration file -d, --daemon Make server run as a Daemon. -u, --debugger Enable ruby-debugging for the server. -e, --environment=name Specifies the environment to run this server under (test/development/production). Default: development -P, --path=/path Runs Rails app mounted at a specific path. Default: / -h, --help Show this help message.
$ script/console --help Usage: console [environment] [options] -s, --sandbox Rollback database modifications on exit. --irb=[irb] Invoke a different irb. --debugger Enable ruby-debugging for the console.
$ script/dbconsole --help Usage: dbconsole [options] [environment] -p, --include-password Automatically provide the password from database.yml --mode [MODE] Automatically put the sqlite3 database in the specified mode (html, list, line, column). -h, --header $
Even if you're new to Rails, you likely know that
script/server requires the
-e flag to specify an environment other than the default, development. I can't count how many times I've run the command correctly. At the end of a productive day when I was tired, though, I just ran it like I had been running
script/dbconsole throughout the day, without
Notice also that
[environment] [options] while
[options] [environment]. Fortunately, that didn't bite me and compound the problem.
3.0 3.1 is better
The inconsistencies among
script/dbconsole described above are from the scripts included in a Rails 2.3 app. Unfortunately, Rails 3.0 is no different. Although Rails 3.1 addresses the inconsistency between
rails console and
rails dbconsole (the commands were renamed in Rails 3.0 and later), the inconsistency between those two commands and
rails server remains. It probably will for the foreseeable future: the server command has expected
-e for as long as I can remember. Perhaps the inconsistency can be discussed when the next major release is on the horizon, since addressing it will break backwards compatibility.
Inconsistent APIs slow us down and frustrate us, all the more so when we aren't at our best. They cost us time and therefore cost our customers money. Keep your APIs consistent, and know which ones among your tools are inconsistent.