I've ran into various problems with various sites over the years with users putting spaces at the start/end of string and text fields. Sometimes these cause formatting/layout problems, sometimes they cause searching problems (ie search order looking wrong even though it isn't really), sometimes they actually crash the app.
I thought it would be useful, rather than putting in a bunch of before_save callbacks as i have done in the past, to add some functionality to ActiveRecord to automatically call .strip on any string/text fields before saving, unless i tell it not to, eg with do_not_strip :field_x, :field_y
or something similar at the top of the class definition.
Before i go and figure out how to do this, has anyone seen a nicer solution? Just to be clear, i already know that i can do this:
before_save :strip_text_fields
def strip_text_fields
self.field_x.strip!
self.field_y.strip!
end
but i'm looking for a nicer way.
cheers, max
Here's a handy module that you could drop into lib and include in your models. It doesn't have the exceptions that you mentioned, but it looks for a strip!
method which might be good enough. You could add the exceptions feature fairly easily, if needed.
# lib/attribute_stripping.rb
module AttributeStripping
def self.included(context)
context.send :before_validation, :strip_whitespace_from_attributes
end
def strip_whitespace_from_attributes
attributes.each_value { |v| v.strip! if v.respond_to? :strip! }
end
end
Use like this:
class MyModel < ActiveRecord::Base
include AttributeStripping
# ...
end
UPDATE (9/10/2013):
Revisiting this answer a couple of years later, I see how the winds have changed. There's a cleaner way to do it now. Create a module like this:
module AttributeStripper
def self.before_validation(model)
model.attributes.each_value { |v| v.strip! if v.respond_to? :strip! }
true
end
end
and set its method to be invoked at the right time in your model:
class MyModel < ActiveRecord::Base
before_validation AttributeStripper
# ...
end
This module is easier to test since it's not a mixin.
I have dealt with these sort of data integrity issues in various applications.
I used to manipulate the input like that.
But now, the best advice I have actually seen and followed is to store whatever the user types. Then do post-processing on the backend to do the strip. Create additional database fields (destripped) if you really want it in the database model table.
The main reason for this is one (primary) thing - when users want to revisit their data, i.e. edit, they're usually gonna expect to see what they typed in. A secondary reason is that you will avoid the possibility that your strip doesn't work right and either mangles the data or actually throw an error.
I've written a plugin for this purpose some time ago. I haven't tried it in a while and it doesn't have tests - so no guaranties that it still works. The upside would be a clean model:
class Story < ActiveRecord::Base
strip_strings :title, :abstract, :text
end
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