Wednesday, 6 June 2007

ruby on rails params and empty strings

A little annoyance I've found using ruby on rails is the following:

If in your model you have some strings that can be null, and the user doesn't fill the related fields in the web form, rails will end up storing an empty string "" instead of the good old NULL in the database.

Now, this is for sure not a big problem but it has some implications that might affect the model validations and it can be even worse if the rails app is not the only program writing in the database, in this last case you easily end up with a mix of empty string and NULL values in the column making trickier to write queries conditions that involve that column.

Now I was playing today to fix this problem and I came with a solution that uses SimpleDescriptor.

For any model that uses SimpleDescriptor as described in this post the following is a way to have NULL saved in the database instead of the empty string ''

first you need to define the clean_strings method

def clean_strings
self.class.described_as(:string).each do { |field| send("#{field}=", nil) if send(field) == '' }

and then add the clean_strings method in your before_validation callback

before_validation :clean_strings

Starting from this moment your model will just save NULL instead of an empty string and the :allow_nil => true in the model validations will start behaving as expected.


Anonymous said...

I ran into a similar problem while using DataMapper. I wound up adding this line to property.rb in the dm-core gem for the typecast method. The to_date typecast was barfing when it encountered an empty value for a date which was allow_nil in the model.

return nil if value.empty?

hungryblank said...

I just want to add that patching directly the code in dm-core is a very bad practice, I don't have specific datamapper experience but I'd be surprised if it wouldn't be possible to achieve the same using a callback