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.
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
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With