07
Jan
09

Take Control of your Field Values with nilify_blanks

If in your data schema most or all of your fields are NULLable (the Rails default in migrations), you may have run into the issue whereby sometimes your fields are blank and sometimes they are NULL, two distinct representations of a “no data” state.  This arises in Rails often because when you submit a form and the user doesn’t fill in a value, the value sent to the database is an empty string, even if you may prefer the field to just remain NULL.

Enter nilify_blanks, my solution to handling this problem generically in your models.  With nilify_blanks you can specify the fields you want “nilified” (or default to all content fields) upon save if the field is blank.  This allows you to regain some consistency in how you represent data in the database.   Use of the plugin is best-explained with some examples:

Basic Examples

  # Checks and converts all fields in the model
  class Post < ActiveRecord::Base
    nilify_blanks
  end

  # Checks and converts only the title and author fields
  class Post < ActiveRecord::Base
    nilify_blanks :o nly => [:author, :title]
  end

  # Checks and converts all fields except for title and author
  class Post < ActiveRecord::Base
    nilify_blanks :except => [:author, :title]
  end

Specifying a Callback
Checking uses an ActiveRecord before_save filter by default, but you can specify a different filter with the :before option. Any filter will work – just first remove the “before_” prefix from the name.

  class Post < ActiveRecord::Base
    nilify_blanks :before => :create
  end

  class Post < ActiveRecord::Before
    nilify_blanks :before => :validation_on_update
  end

12 Responses to “Take Control of your Field Values with nilify_blanks”


  1. 1 planetmcd Jan 8th, 2009 at 2:33 pm

    This is an f&^%&% awesome idea. I can’t wait to try it. I can’t tell you how much the empty string bothers me and I don’t understand why it is not the default behavior. Thanks for doing this.

  2. 2 Jay Levitt Jan 8th, 2009 at 3:32 pm

    Neat! Does this preserve the distinction between NULL/nil and blank, or does it just change all blanks into NULLs? In other words, if I have a field that’s legitimately blank, will it stay blank if it passes through a form, or will this turn it into NULL?

  3. 3 benhughes Jan 8th, 2009 at 11:17 pm

    Jay – if you use this plugin on your model, by default all fields that respond to blank? and return true for it will be converted to nils. Any fields that can “legitimately” be blank must be excepted from the columns like this: nilify_blanks :except => [:can_be_blank].

    Also, to be clear, *all* the fields that get converted are checked upon every save, regardless of whether a value has or has not been set. In other words if you have a blank field in the model then have a form that does *not* include that field (hence no key provided for it in update_attributes, for example), that blank field will still be converted to nil. It works as a before_save filter, not by overriding the mutators.

  4. 4 Joe Jan 9th, 2009 at 5:28 pm

    Another plugin for doing this is strip_attributes

  5. 5 Ed W Jan 25th, 2009 at 11:22 pm

    Better also to remove the trinary logic and make fields NOT NULL unless it’s particularly useful…

  6. 6 gindogg Feb 27th, 2009 at 11:12 pm

    I followed the readme install instructions and the gem shows up when I run “gem list.” However, I receive “undefined local variable or method `nilify_blanks’”. Not sure what I’m missing.

  7. 7 benhughes Mar 9th, 2009 at 7:22 pm

    Looks like there was a problem with this working in gem mode; this should be solved and now working as of the latest version (0.1.1) – just update the gem and it should work now.

  8. 8 Andreas May 26th, 2009 at 9:50 pm

    I was looking for exactly this behavior and it is really working well in general. Unfortunately, I ran into a catch 22 situation. When running my migrations, I get the following error – tables don’t exist yet. Only commenting the nilify_blanks line gets me passed this issue. Here is the relevant stack trace fragment:

    Mysql::Error: Table ‘ll_prd.organizations’ doesn’t exist: SHOW FIELDS FROM `organizations`
    /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract_adapter.rb:188:in `log’
    /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/mysql_adapter.rb:309:in `execute’
    /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/mysql_adapter.rb:440:in `columns’
    /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1220:in `columns’
    /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1239:in `content_columns’
    /Library/Ruby/Gems/1.8/gems/railsgarden-nilify_blanks-0.1.1/lib/nilify_blanks.rb:24:in `nilify_blanks’

  9. 9 benhughes May 28th, 2009 at 2:21 am

    Ah great catch – I’ve changed the plugin to only activate if the table exists. Thanks!

  10. 10 Julio Capote Aug 31st, 2009 at 8:41 pm

    Perhaps I’m confused, but what’s wrong with just having :default => nil? in your migrations?

  11. 11 Gavin Hughes Oct 26th, 2009 at 9:29 pm

    Nice work, Ben. Exactly what I was looking for.

  12. 12 benhughes Jan 3rd, 2010 at 4:28 pm

    By default columns are nil anyways, so :default => nil is really unnecessary. What this plugin solves is when a form is submitted with a blank value which explicitly gets set as so in the database. For example if your params hash is:

    { :name => “Project A”, :description => “” }

    Perhaps you really want the “description” field to be NULL in the database and not “” as it will be by default.

Leave a Reply




  • Ben Hughes

    I'm a freelance developer working with Ruby and other modern tools to build web applications, based currently out of Rochester, NY. I love to learn about new technologies and am always trying to achieve elegance and beauty through code.

    When I'm not writing software, I like to play tennis, dabble in jazz piano, and ponder economics. I'm a big fan of: world travel and cultures, jazz music, Korean food, coffee, and having interesting conversations.

  • Recommend Me
January 2009
M T W T F S S
« Dec    
 1234
567891011
12131415161718
19202122232425
262728293031