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 :only => [: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


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.
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?
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.
Another plugin for doing this is strip_attributes
Better also to remove the trinary logic and make fields NOT NULL unless it’s particularly useful…
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.
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.
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’
Ah great catch – I’ve changed the plugin to only activate if the table exists. Thanks!
Perhaps I’m confused, but what’s wrong with just having :default => nil? in your migrations?
Nice work, Ben. Exactly what I was looking for.
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.
FYI – The github link near the top of this article does not work. Seems to point to your old railsgarden identity, not your rubiety account.
Thanks! This has been fixed.