Database fields are polluted with both nil and empty '' values when submitting forms

We see problems with this as well. I’m actually wondering if maybe it should go the other way, though, and we should default columns to empty string. The purist in me wants them to be nil, but if we’re having to go out of our way to modify strings in a bunch of places, then maybe we’re going against the grain. We’ve got similar issues in JSONB columns where we might have an empty hash or nil. I’m beginning to think we just get rid of the nil case entirely. It means we have to check if thing.present? instead of if thing, but I guess I can live with that.

With regards to people who distinguish between nil and '', this seems like it might be better served by having some sort of explicit status somewhere to track progress through a wizard, or whether certain fields have been configured. I shy away from assigning meaning to nil, since there are a lot of things that could result in a nil value, some of which may represent a subtle bug. With an explicit signifier we’ve got a much clearer indication of what the expected state is.


No. Don’t do that. An empty string is something different than a null value:

null means ‘I do not know what the value is’ empty string means ‘the value is known and it is the empty string’

Likewise Rails should not put empty strings in fields that are not set. I think that is an outright bug. It clobbers not null constaints by putting an empty string in.

But I cannot. The semantics of a nil value are totally different from the semantics of an empty value.

Yes well that’s a programmer too lazy to keep proper state in forms.

Surprised no one has mentioned nilify_blanks!

@ruurd can you talk a bit more about why we should keep them as empty strings? Having trouble wrapping my head around why we’d want to differentiate.

EDIT: I just found this article on the subject and found it very enlightening

Primarily it is a question of truth maintenance. An empty string is a known value that has no content, in other words, we know the value of the string and it does not contain any characters, a null string is an unknown value, i.e. we know we can make it contain a string value but at the moment we do not know what the value should be.

A lot of people conflate null and empty strings but from a truth maintenance point that is unjustifiable.

In the example in the article, null for the middle_name means we do not know the middle_name, an empty middle_name means we know the middle_name to be empty. It looks like a minor detail but that really is not the case. So no - a null middle name is something different than an empty middle name.


I think this “WTF” is nicely solved thanks to Jonathan Hefner. :heart:

The Rails 7.1 release (now in beta) adds ActiveRecord::Base.normalizes in PR#43945.

…now back to replacing my code with something better :smile: