Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Force empty string to NULL in the database

Is there an easy way (i.e. a configuration) to force ActiveRecord to save empty strings as NULL in the DB (if the column allows)?

The reason for this is that if you have a NULLable string column in the DB without a default value, new records that do not set this value will contain NULL, whereas new records that set this value to the empty string will not be NULL, leading to inconsistencies in the database that I'd like to avoid.

Right now I'm doing stuff like this in my models:

before_save :set_nil  def set_nil   [:foo, :bar].each do |att|     self[att] = nil if self[att].blank?   end end 

which works but isn't very efficient or DRY. I could factor this out into a method and mix it into ActiveRecord, but before I go down that route, I'd like to know if there's a way to do this already.

like image 300
Thilo Avatar asked Aug 26 '11 08:08

Thilo


2 Answers

Yes, the only option at the moment is to use a callback.

before_save :normalize_blank_values  def normalize_blank_values   attributes.each do |column, value|     self[column].present? || self[column] = nil   end end 

You can convert the code into a mixin to easily include it in several models.

module NormalizeBlankValues   extend ActiveSupport::Concern    included do     before_save :normalize_blank_values   end    def normalize_blank_values     attributes.each do |column, value|       self[column].present? || self[column] = nil     end   end  end  class User   include NormalizeBlankValues end 

Or you can define it in ActiveRecord::Base to have it in all your models.

Finally, you can also include it in ActiveRecord::Base but enable it when required.

module NormalizeBlankValues   extend ActiveSupport::Concern    def normalize_blank_values     attributes.each do |column, value|       self[column].present? || self[column] = nil     end   end    module ClassMethods     def normalize_blank_values       before_save :normalize_blank_values     end   end  end  ActiveRecord::Base.send(:include, NormalizeBlankValues)  class User end  class Post   normalize_blank_values    # ... end 
like image 126
Simone Carletti Avatar answered Sep 19 '22 06:09

Simone Carletti


Try if this gem works:

https://github.com/rubiety/nilify_blanks

Provides a framework for saving incoming blank values as nil in the database in instances where you'd rather use DB NULL than simply a blank string...

In Rails when saving a model from a form and values are not provided by the user, an empty string is recorded to the database instead of a NULL as many would prefer (mixing blanks and NULLs can become confusing). This plugin allows you to specify a list of attributes (or exceptions from all the attributes) that will be converted to nil if they are blank before a model is saved.

Only attributes responding to blank? with a value of true will be converted to nil. Therefore, this does not work with integer fields with the value of 0, for example...

like image 25
dexter Avatar answered Sep 19 '22 06:09

dexter