Rails 3 strip whitespace before_validation on all

2019-04-07 19:17发布

问题:

I'm relatively new to Rails and a bit surprised this isn't a configurable behavior...at least not one I've been able to find yet?!? I would have thought that 99% of forms would benefit from whitespace being trimmed from all string & text fields?!? Guess I'm wrong...

Regardless, I'm looking for a DRY way to strip all whitespace from form fields (of type :string & :text) in a Rails 3 app.

The Views have Helpers that are automatically referenced (included?) and available to each view...but Models don't seem to have such a thing?!? Or do they?

So currently I doing the following which first requires and then includes the whitespace_helper (aka WhitespaceHelper). but this still doesn't seem very DRY to me but it works...

ClassName.rb:

require 'whitespace_helper'

class ClassName < ActiveRecord::Base
  include WhitespaceHelper
  before_validation :strip_blanks

  ...

  protected

   def strip_blanks
     self.attributeA.strip!
     self.attributeB.strip!
     ...
   end

lib/whitespace_helper.rb:

module WhitespaceHelper
  def strip_whitespace
    self.attributes.each_pair do |key, value| 
    self[key] = value.strip if value.respond_to?('strip')
  end
end

I guess I'm looking for a single (D.R.Y.) method (class?) to put somewhere (lib/ ?) that would take a list of params (or attributes) and remove the whitespace (.strip! ?) from each attribute w/out being named specifically.

回答1:

Create a before_validation helper as seen here

module Trimmer
  def trimmed_fields *field_list  
    before_validation do |model|
      field_list.each do |n|
        model[n] = model[n].strip if model[n].respond_to?('strip')
      end
    end
  end
end

require 'trimmer'
class ClassName < ActiveRecord::Base
  extend Trimmer
  trimmed_fields :attributeA, :attributeB
end


回答2:

Use the AutoStripAttributes gem for Rails. it'll help you to easily and cleanly accomplish the task.

class User < ActiveRecord::Base
 # Normal usage where " aaa   bbb\t " changes to "aaa bbb"
  auto_strip_attributes :nick, :comment

  # Squeezes spaces inside the string: "James   Bond  " => "James Bond"
  auto_strip_attributes :name, :squish => true

  # Won't set to null even if string is blank. "   " => ""
  auto_strip_attributes :email, :nullify => false
end


回答3:

Note I haven't tried this and it might be a crazy idea, but you could create a class like this:

MyActiveRecordBase < ActiveRecord::Base
  require 'whitespace_helper'  
  include WhitespaceHelper
end

... and then have your models inherit from that instead of AR::Base:

MyModel < MyActiveRecordBase
  # stuff
end