How to trim input in rails models globally
In my Rails app there are several models where users are posting data to the database. Lots of this data has trailing and leading whitespaces. Is there a way I can globally strip all input's leading and trailing whitespaces?
I'd like to avoid doing this for every field in every model, seems like there could be a global way to handle this during a before_save
.
An开发者_高级运维y used techniques out there?
Thanks
One more gem to do this job: https://github.com/holli/auto_strip_attributes
Also in some cases you want to squish the data user has inputted to get rid of multiple spaces inside the variable. E.g. with names or nicks.
gem "auto_strip_attributes", "~> 1.0"
class User < ActiveRecord::Base
auto_strip_attributes :name, :nick, :nullify => false, :squish => true
end
All the gems and other approaches work a bit the same way by using before_save callback. (Code example is in Jeremys example.) So there might be some issues with custom setters. You can choose to do it with
attributes.each do before_validation do ...
record.send("#{attr_name}=", record.send(attr_name).to_s.strip)
or with
attributes.each do before_validation do ...
record[attribute] = record.send(attr_name).to_s.strip)
First approach will call setter twice (once when setting, once in before_validation). The second will call setter only once but will alter the data after the call to setter.
Here is one simple way to do it on selected attributes:
module ActiveRecord
module Acts
module AttributeAutoStripper
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def acts_as_attribute_auto_stripper (*names)
class_eval <<-EOV
include ActiveRecord::Acts::AttributeAutoStripper::InstanceMethods
before_validation :auto_strip_selected_attributes
def auto_strip_attributes
#{names.inspect}
end
EOV
end
end
module InstanceMethods
def auto_strip_selected_attributes
if auto_strip_attributes
auto_strip_attributes.each do |attr_name|
self.send("#{attr_name}=", self.send(attr_name).to_s.strip) unless self.send(attr_name).blank?
end
end
end
end
end
end
end
ActiveRecord::Base.send :include, ActiveRecord::Acts::AttributeAutoStripper
and then in your model:
class User < ActiveRecord::Base
acts_as_attribute_auto_stripper :name, :email
end
If users are posting data to the DB through a form, you could create a before filter method that'll strip the parameters. Put that in the Application controller.
I hope this helps :)
This fork of the StripAttributes plugin may do the trick for you:
https://github.com/fragility/strip_attributes
You could create an ActiveRecord subclass with a before_save filter that strips all attributes. Then, make all of your models a subclass of this new class.
精彩评论