Ruby on rails DRY strip whitespace from selective

2020-07-30 06:34发布

问题:

I'm fairly new to rails so bear with me.

I want to strip whitespace from a selective group of input forms.

But I would like a DRY solution.

So I was thinking there might be a solution such as a helper method, or a custom callback. Or a combination such as before_validation strip_whitespace(:attribute, :attribute2, etc)

Any help is awesome! Thanks!

EDIT

I have this in my model file ...

  include ApplicationHelper

  strip_whitespace_from_attributes :employer_name

... and I have this in my ApplicationHelper ...

  def strip_whitespace_from_attributes(*args)
    args.each do |attribute|
      attribute.gsub('\s*', '')
    end
  end

but now I'm getting the error message:

undefined method `strip_whitespace_from_attributes' for "the test":String

EDIT II -- SUCCESS

I added this StripWhitespace module file to the lib directory

module StripWhitespace

  extend ActiveSupport::Concern

  module ClassMethods
    def strip_whitespace_from_attributes(*args)
      args.each do |attribute|
        define_method "#{attribute}=" do |value|
            #debugger
            value = value.gsub(/\s*/, "")
            #debugger
            super(value)
          end
      end
    end
  end

end

ActiveRecord::Base.send(:include, StripWhitespace)

and then added this to any model class this wants to strip whitespace ...

  include StripWhitespace
  strip_whitespace_from_attributes #add any attributes that need whitespace stripped

回答1:

I would go with sth like this (not tested):

module Stripper # yeah!
  extend ActiveSupport::Concern

  module ClassMethods
    def strip_attributes(*args)
      mod = Module.new
        args.each do |attribute|
          define_method "#{attribute}=" do |value|
            value = value.strip if value.respond_to? :strip
            super(value)
          end
        end
      end
      include mod
    end
  end
end

class MyModel < ActiveRecord::Base
  include Stripper
  strip_attributes :foo, :bar
end

m = MyModel.new
m.foo = '   stripped    '
m.foo #=> 'stripped'     


回答2:

If you can get your attributes in to a single array (perhaps there's a [:params] key you can use instead), you can do the following:

class FooController < ApplicationController
  before_create strip_whitespace(params)



  private

  def strip_whitespace(*params)
    params.map{ |attr| attr.strip }
  end
end