Ever added the uniqueness validation to a model
class Person < ApplicationRecord validates :name, uniqueness: { case_sensitive: false } end
but just adding the above alone will not prevent the duplicates
Soon you will start seeing duplicates and you’ll wonder how’s that happening. After spending some time (or hours) debugging you will notice that users are adding extra white spaces to bypass the uniqueness validation. Smart hn!!
Bagel & Cream Cheese Bagel & Cream Cheese Bagel & Cream Cheese
Means now you have to take care of extra white space, and in many models. Lets create a module to handle that.
module StripedColumns def self.included(base) base.extend ClassMethods end module ClassMethods StripedColumnsDefaultOptions = { squeeze: false } # add has_striped_columns as a class method def has_striped_columns(options = StripedColumnsDefaultOptions) options[:squeeze] = { string: true, text: true } if options[:squeeze] == true before_validation do self.class.columns.each do |column| # only run for String or Text columns next unless column.type.in? %i(string text) # make sure value is not nil next unless value = self.send(column.name) # run :if condition passed as options next unless options[:if].to_proc.call(self) if options[:if] # check if value is a string if value.kind_of?(String) # remove white spaces around the text value = value.strip # grab the value after running the options value = apply_striped_columns_options(column, value, options) # assign the new value to the column self.send("#{column.name}=", value) end end end end end private def apply_striped_columns_options(column, string, options) if squeeze_opts = options[:squeeze] if (squeeze_opts[:string] == true && column.type == :string) || (squeeze_opts[:text] == true && column.type == :text) # remove extra white spaces between words string = string.squeeze(" ") end end string end end # add it to ActiveRecord::Base to make it available to all the models ActiveRecord::Base.include(StripedColumns)
That little module will handle all the extra white space issues
class Person < ApplicationRecord # has_striped_columns # remove spaces around # has_striped_columns, if: :is_true? # remove spaces around only if is true # has_striped_columns, squeeze: true # remove spaces around + remove extra space between words # has_striped_columns, squeeze: :string # remove spaces around + remove extra space between words for string column only # has_striped_columns, squeeze: :text # remove spaces around + remove extra space between words for text column only validates :name, uniqueness: { case_sensitive: false } end