The Lowdown

My name is Jaime Bellmyer, and I'm a Ruby on Rails developer in Kansas City. I work at a great company, and I'm available for freelance projects, as well.

A little over a year ago I was a Perl developer from Omaha, recently brought down to Kansas City because my "mad perl skillz" were in high demand. Almost as soon as I got here, that all changed when my company became a Ruby on Rails shop. I'm glad that happened right after I was hired, because I love Kansas City, and Ruby on Rails!

The Blog

Ruby on Rails: Bool vs. Boolean in SQLite3

Posted by Jaime Bellmyer Tue, 15 Jul 2008 16:15:00 GMT

I was looking at a new (to me) project today, and stumbled across a rails "gotcha" that needs attention. I tried to run rake test, but it failed. I received this error on each and every test:

rake test
  SQLite3::SQLException: no such table

There are something like 60 migrations in this project, so I went (almost) straight to db/schema.rb which gives you the all-in-one look at your database structure. That's where I stumbled on this:

db/schema.rb
  # Could not dump table "generic_table" because of following StandardError
  #   Unknown type 'bool' for column 'generic_column'

it turns out a field was created with the type bool. I'm using SQLite3 for this project, but I did flip over to MySQL during debugging. Here's what I found:

Under MySQL, bool and boolean appear to work just fine as column types. schema.rb is fine, tests are fine, and these two descriptors are synonymous.

Under SQLite3, boolean is the correct field descriptor. bool won't break your migration, but:

  • rake db:schema:dump (which is called by rake db:migrate) will fail SILENTLY, and your schema.rb file will be corrupted.
  • rake db:test:prepare uses schema.rb, so it will fail, also SILENTLY.
  • tests will fail
  • rake db:reset also uses schema.rb, and so it will recreate a broken database.
  • Oddly, the bool field in ruby will return 'f' for false, and 't' for true. If you set it to true, it does the "magic" on the backend, and there will be a 't' in that field. Therefore, setting something to false doesn't really work, because that field contains 'f', which equates to true.

Rails will do all of this without complaint. Your migrations, db:test:prepare, even code will run without raising red flags. Scary. Tests are where things will start breaking.

Posted in , ,  | Tags , , , , , , , ,  | no comments

New Laptop Day!

Posted by Jaime Bellmyer Fri, 11 Jul 2008 15:22:00 GMT

I got my new laptop yesterday. Why? Because I took a new and exciting job, and I'll flesh out the details after I've been there for a week or two. Suffice to say, the company seems great, and I'm excited! In the meantime, let's look at some specs:

Dell Precision M6300
 - 17" Screen
 - Intel Core 2 Duo processor(s), 2.5GHz each
 - 2GB Dual-Channel RAM
 - 80GB 7200RPM Hard Drive
 - Dual-Band Wireless Card
 - High Level of Badassery

The only "problem" I have with this machine is that it won't fit in my current backpack, which maxes out at 15.4" screen laptops. That prompted me to put together this list of, what I feel, are the most important considerations. This is after having carried my current (and first) laptop backpack around for over a year.

Laptop Backpack Requirements

Capacity

This thing is a monster. At 15.5"x11.3" and just over 1.5 inches thick, it makes my current Dell Latitude look like a kiddy toy. It's also rugged looking, as though Charlton Heston and the lead designer of the Ford F-150 had a lovechild, who grew up to design laptops for Dell. Anyway, this seems to be pushing the norm for laptop sizes, so I need a bag that is specifically designed to carry it.

Breathable Back

My laptop bag serves a very functional purpose. I use both straps and tend to carry lots of stuff with me. With my new job, I plan to do even more walking since I'll be working remotely. Breathable mesh backs will hopefully limit overall sweatiness and discomfort.

Strap Connector Thingy

Maybe you've noticed, but some backpack straps actually connect across your chest, and this is a huge difference in comfort when you walk. With the weight of a computer/books on your back, the backpack will sag, causing you to pull it back up periodically. Maybe you've seen (or been) someone who walks with their thumbs tucked under the straps. This is not JUST so that their thumbs can soak up all that awesome underarm aroma. They're keeping the straps in place. Chest connector thingies do this for you.

Here's a summary of these, and other considerations. I'd love feedback and possibly leads. I'm willing to spend up to around $100 because I'll have this for a while, and I plan to be mobile.

Ideal Laptop Backpack
 - Capacity for a 17" screen laptop
 - Breathable back
 - Strap connector thingies
 - Two straps - the single sling doesn't look comfy for long walks
 - Must say, "I'm a geek, but I make a reasonable effort to be fashionable."

Posted in  | Tags , , , , ,  | no comments

Do Not Buy Dell "Open-Source" Laptops

Posted by Jaime Bellmyer Sat, 28 Jun 2008 14:27:00 GMT

I'm pricing out laptops on Dell, and I was intrigued by their "open-source" option. What that essentially means is, you don't get Windows with it. You get a basic command-line operating system (FreeDOS) that allows you to install the operating system of your choice, presumably because you want to use an open-source option like Linux.

You would think that skipping windows would result in a price drop, and indeed the starting price is lower - by $39. The windows version starts with a slightly slower processor, but the DOS version starts with half the RAM. I walked through and built out identical laptops, the only difference being whether or not Windows Vista was installed. Here are the specs for each system, then the specs for the custom system I built out on each, to make them identical:

Feature Dell Latitude D830 Dell Latitude D830N Custom
Operating System Windows Vista Basically Nothing Unchanged
Base Price $809 $770 N/A
Processor Intel Duo 2.00 GHz Intel Duo 2.20 GHz Intel Duo 2.50 GHz
Warranty 3 Year Mail-In 3 Year Mail-In 3 Year On-Site
Screen 15.4" WXGA 15.4" WXGA 15.4" WXGA
Memory 1GB, 2 DIMMs 512MB, 1 DIMM 2GB, 2 DIMMs
Hard Drive 80GB, 5400 RPM 80GB, 5400 RPM 80GB, 7200 RPM
Optical 24x CD-RW, DVD-ROM 24x CD-RW, DVD-ROM 8x DVD-RW
Graphics Card Integrated Integrated 256MB dedicated
Wireless Dell 802.11g Dell 802.11g Intel 802.11a/g, Dual Band
Battery 6 Cell 6 Cell 9 Cell
Final Price $1,426 $1,396 N/A

The difference, after evening out the uneven features and adding some things I wanted, is $30. How much is Windows Vista?? I know they get it at a discount, but $30 is such a small token amount, it's almost a slap in the face. If I choose not to buy a couple hundred dollar operating system, I should save a couple hundred dollars.

I say for the $30, get the one with Windows pre-installed. You can still overwrite or even dual-boot, and you'll always have the Windows license if you want/need it.

Posted in ,  | Tags , , , ,  | no comments

Kansas City Ruby Users Group

Posted by Jaime Bellmyer Wed, 25 Jun 2008 17:16:00 GMT

I just attended my first KCRUG meeting last night, and it was awesome. This, despite being told the wrong room number and therefore missing the first 30 minutes of the meeting. And getting roped into that wrong room even after realizing my mistake, by a zealous .NET developer who wanted me to join their group. I code RoR on Ubuntu, but they have free pizza. I'm considering it.

To the friends I met - Sam, Steven (or Stephen?), John, David, Sean, and Scotty - thanks for making my attendance slightly less awkward. Looking forward to next time!

Posted in ,  | Tags , , ,  | no comments

Microsoft SharePoint Squares Off Against the Competition

Posted by Jaime Bellmyer Tue, 24 Jun 2008 18:10:00 GMT

While debating the value of SharePoint with a friend, I hopped onto microsoft.com to get some ammo, and boy did I find it. This is a direct quote from microsoft:

http://office.microsoft.com/en-us/sharepointdesigner/HA101314471033.aspx
  Based on ASP.NET technology, SharePoint sites offer powerful, flexible
  support for interaction and collaboration. More traditional, static Web
  sites that are not based on ASP.NET may provide an effective venue for
  one-way presentations, but they cannot support true collaboration of
  the sort that Windows SharePoint Services 3.0 and ASP.NET 2.0 make possible.

SharePoint vs. Static HTML??? I love this marketing strategy: compare your most advanced offering with the oldest and most feature-poor alternative. The best part is, even the lamest marketer (me) can do it:

Me, being a bit of a jackass
  The latest Geo Metro is a modern marvel of engineering and safety.  The
  more traditional 1971 Ford Pinto, in contrast, has been called "the barbecue
  that seats four".  If you wish to roast yourself and your family in a firey grave,
  by all means purchase the Pinto.

Posted in , ,  | Tags , , ,  | no comments

Ruby on Rails Schema Migration using schema.rb

Posted by Jaime Bellmyer Tue, 24 Jun 2008 17:06:00 GMT

A few months ago, we had a problem. We had a (relatively) mature application we wanted to deploy to a new server. In this case, waited to deploy to the production server until after several weeks of development/testing in stage. We deployed via Webistrano, then we tried to deploy:migrate, and that's where things went south.

Migrations that were written and worked with version X of our app failed 10 versions down the road. You're especially vulnerable when something that was a model attribute (ergo, a table field) before is now an instance method, or vice versa. For example, maybe password starts out as an attribute, but later becomes a method because you want password=(x) to generate a hash.

If you're doing a fresh setup on a new server, and your app has been through several migrations already, you should ditch migrations for the initial deploy and run db/schema.rb instead, with the command rake db:schema:load. It will create the latest version of your database schema, including the current version number so future migrations will run without a problem.

There is even a note about this in db/schema.rb itself, which I just found today:

helpful hint provided in schema.rb itself
  Note that this schema.rb definition is the authoritative source for your
  database schema. If you need to create the application database on another
  system, you should be using db:schema:load, not running all the migrations
  from scratch. The latter is a flawed and unsustainable approach (the more
  migrations you'll amass, the slower it'll run and the greater likelihood
  for issues).

Also, db/schema.rb is a great place to see the current state of your tables! Just this morning I returned to a dusty project, and needed to know what table fields already existed, and which I needed to add. In fact, that's how I stumbled on the above notice.

Posted in , ,  | Tags , , , , , , ,  | no comments

Ruby on Rails BDD Can be Creepy

Posted by Jaime Bellmyer Mon, 23 Jun 2008 17:22:00 GMT

As an exercise in getting more comfortable in RSpec, I'm porting over some unit tests so my current app (a CMS to administer our online games) can be 100% RSpec moving forward. The keyword it becomes funny and creepy the more you use it, and I found myself writing this:

creepy ruby
  describe "An editor user" do
    it "should have read privileges"
    it "should have editor privileges"
    it "puts the lotion on its skin"
  end

Then for fun, I wrote this up:

creepier ruby
  describe Captive do
    fixtures :captives
	
    it "puts the lotion on its skin" do
      captive(:girl).should be_moisturized
    end
  end

Yeah, it's sick, but it made me laugh so I thought I'd share. Maybe RSpec should have "he" and "she" aliases to make describing person-based models less creepy. Just kidding - I'm having trouble memorizing all the natural-language idioms as it is.

Posted in , ,  | Tags , , , , , ,  | no comments

Building Reliable Tests in Ruby on Rails

Posted by Jaime Bellmyer Fri, 20 Jun 2008 16:30:00 GMT

I've recently delved into TDD (test-driven development) and it's snobbier cousin BDD (behavior-driven). They both rock. Like many, I'm starting to see BDD as the evolutionary next step after TDD. I was somehow conditioned to think Rspec was evil and complicated, but it's growing on me.

When is 10 less than 9?

The answer is, when ruby sees them as strings. This is an issue with loosely typed languages like ruby. This recently caught a coworker off guard, and the worst part is that his automated testing did not catch the problem. This caused him to express frustration and doubt with testing in general.

A good rule of thumb that I use, and I've heard it echoed all over the knowledgeable net, is to purposely break each test when you create it. Test the test. If this sounds tedious, it's actually very quick in practice. Let's look at some code:

a simple unit test
  def test_001_new_user_should_be_active_by_default
    user = User.new
    assert user.active?, "New user should be active by default"
  end

Or in rspec:

a simple rspec test
  describe "A new user" do
    before(:each) do
      @user = User.new
    end

    it "should be active by default" do
      @user.should be_active
    end
  end

This simply ensures a user is active by default. Behind the scenes I imagine a status attribute with a default value of 'active', and an instance method called User#active? to check if a user is active. But before I put all my faith into this, I'll purposely poke it to make sure it screams when needed:

temporarily breaking the unit test
  def test_001_new_user_should_be_active_by_default
    user = User.new(:status=>'inactive')
    assert user.active?, "New user should be active by default"
  end

And again, the rspec version:

temporarily breaking the rspec test
  describe "A new user" do
    before(:each) do
      @user = User.new(:status=>'inactive')
    end

    it "should be active by default" do
      @user.should be_active
    end
  end

I run the purposely broken test, see that it screams, and now I can undo that last tweak, confident that my test will work when needed.

Another popular method is to curse at your tests when they let you down. But this is negative reinforcement, which any childless freshman psych major will say is never the answer.

UPDATE: Forgive my newness with TDD/BDD, but if you're doing either of these in their most pure form, you eliminate a LOT of test reliability worries. This is because you write the tests first, and of course they fail right away, until you add the code that makes them work.

Posted in , ,  | Tags , , , , , , , , , ,  | no comments

Hack Your Pedometer

Posted by Jaime Bellmyer Wed, 18 Jun 2008 02:44:00 GMT

Not everything is about rails.

If you work at my company, then you might just be part of the new walking initiative that kicked off this week. We were all given pedometers, and have experienced varying levels of success getting them to accurately measure our steps. Ladies and gentlemen, I give you the guide to hacking your pedometer to make it more accurate.

This can be done by everyone. Not all hacks require mad computer skillz or a flagrant disregard for the law. Sometimes it's just looking at something and saying, How can I make this work for me, in a way it was never intended?" Let's look at some pictures.

This is everything you'll need. A tiny phillips screwdriver, tweezers, cotton swabs, rubbing alcohol, and of course your pedometer. Drinking alcohol is optional, but highly encouraged.

On the back are two tiny screws. Unscrew them, and open up the case. Set the plastic back aside for now.

This is the inside of your pedometer. The arm at the top is attached to a tiny spring, and bounces up and down as you walk. Each time it strikes the metal stopper below, an electrical circuit is formed, and the counter increments itself by one step.

In the bottom right corner is the battery, under a metal brace. gently push the battery down and to the right, using the screwdriver. Take note of which way the battery faces, so you can put it back the same way.

Dip a cotton swab in the smallest possible amount of rubbing alcohol. You don't want it dripping wet, just moist. Now swab the two metal parts that touch with each step, to remove any oils or corrosion. Even the slightest smudge means you're missing steps.

Rotate the pedometer so the battery is at the top, and you'll see the top of the spring that attaches to a strip of metal with five holes. The middle hole is best, but if your pedometer is too sensitive, or not sensitive enough, try using the tweezers to move the spring over in one direction or the other.

This is trial and error. After each adjustment, set the pedometer upright and gently bounce it to simulate walking. Be very careful with the spring, this is the most delicate part of the whole setup, and bending it will make your pedometer cry.

Afterward, replace the battery and reattach the plastic backing. If your pedometer looks like the picture above, chances are, you're in good shape. Enjoy a wonderful lifetime of fitness together. Until the battery dies, and you realize it's just cheaper to buy a whole new one.

Posted in  | Tags , ,  | no comments

Ruby on Rails Testing: assert_equal is Your Friend

Posted by Jaime Bellmyer Mon, 16 Jun 2008 21:34:00 GMT

If you're not already doing tons of unit testing, then shame on you. Let me give you the rundown on good testing:

  • Push as much code into the models (class definitions) themselves.
  • Controllers should mostly just call class methods, and be very small.
  • By following the previous two rules, you've made it very easy to test your application. Controllers are slightly complicated to test, but models are super easy. So write tests for every model method, and write assertions for each expected input/output combination.

Now that we have Testing 101 out of the way, are you doing this?

bad testing
  def test_remove_all_games
    Game.remove_all!
    assert Game.find(:all).length == 0,
        "There should be zero games left."
  end

This will work, provided you've created a "remove_all!" class method for Game that does what it says. However, there's a much more useful way: assert_equal. A good general rule is this: whenever you use the generic assert method, you should ask yourself if there's a more specific method you could be using. Use this page from the ruby api. Let's look at some code:

good testing
  def test_remove_all_games
    Game.remove_all!
    assert_equal 0, Game.find(:all).length,
        "There should be zero games left"
  end

Notice I put the zero first. This is a little counter-intuitive to me, but it's important. The first parameter is what you're *expecting*, and the next is what you have. And you can pass anything into this - numbers, strings, objects, even arrays of objects:

great testing
  def test_remove_all_games
    Game.remove_all!
    assert_equal [], Game.find(:all),
        "There should be no games left"
  end

Why do this? Because the testing will output what was expected and what you received, automatically. It makes for much easier debugging. Try it and see.

Posted in ,  | Tags , , ,  | no comments

Older posts: 1 2 3 ... 5