Skip to content


Fun Little ActiveRecord Gotcha

So I was cruising along adding a new model to a project. The model is being used to store credit card information and when I generated the model, I absentmindedly did:

$ script/generate model CreditCard ... encrypted_expiration_date:date ...

Chugging along writing my tests I wrote a test like this:

class CreditCardTest  < ActiveSupport::TestCase
  context "A CreditCard instance" do
    subject { CreditCard.new(:expiration_date => new_expiration_date) }
    should("ensure expiration_date is encrypted") do
      assert_equal expiration_date_cipher_text, subject.encrypted_expiration_date
    end
    def new_expiration_date; Date.today+90; end
    def expiration_date_cipher_text; "!!!EXPIRATION_DATE_CIPHER_TEXT!!!"; end
  end

And the model looking something like this:

class CreditCard < ActiveRecord::Base
  def expiration_date=(exp_date)
    @expiration_date = exp_date
    self.encrypted_expiration_date = encrypt(exp_date)
  end
end

The test would fail every time like:

Finished in 0.030941 seconds.

  1) Failure:
test:  should encrypt expiration_date. (CreditCardTest)
    [test/unit/credit_card_test.rb:53:in `__bind_1261076018_868915'
     shoulda (2.10.2) [v] lib/shoulda/context.rb:351:in `call'
     shoulda (2.10.2) [v] lib/shoulda/context.rb:351:in `test:  should encrypt expiration_date. ']:
<"!!!EXPIRATION_DATE_CIPHER_TEXT!!!"> expected but was
.

1 tests, 1 assertions, 1 failures, 0 errors

Can you guess the problem? Ten points to Gryffindor if you said it’s because the column type is date. And another five points if you can say it’s because ActiveRecord is tries to parse it to be a date object, which fails, and returns nil.

Posted in Rails, Ruby, Software Development, Tips and Tricks.


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.