Instance Variables in class not being saved

2019-06-04 23:58发布

问题:

I'm filtering all my instance values of my PersonalInfo class via before_validation like this:

  before_validation :strip_tabs

  def strip_tabs
    self.instance_variables.map do |attr|
      value = self.instance_variable_get(attr)
      if value.present? && value.kind_of?(String)
        encoding_options = {
          :invalid           => :replace,  # Replace invalid byte sequences
          :undef             => :replace,  # Replace anything not defined in ASCII
          :replace           => '',        # Use a blank for those replacements
          :universal_newline => true       # Always break lines with \n
        }
        value = value.encode(Encoding.find('ASCII'), encoding_options)
        value = value.squish 
        value = value.gsub("/t","") 
        self.instance_variable_set(attr, value)
      end
    end  
  end

This code was discussed here:

Before Validation loop through self attributes for modification

The strip_tabs works it transforms this: "\t•\tzef" Into this: "zef"

In my test case I fill in last_name with the bad value ("\t•\tzef") and when I set a breakpoint here :

  def strip_tabs
    self.instance_variables.map do |attr|
      value = self.instance_variable_get(attr)
      if value.present? && value.kind_of?(String)
        encoding_options = {
          :invalid           => :replace,  # Replace invalid byte sequences
          :undef             => :replace,  # Replace anything not defined in ASCII
          :replace           => '',        # Use a blank for those replacements
          :universal_newline => true       # Always break lines with \n
        }
        value = value.encode(Encoding.find('ASCII'), encoding_options)
        value = value.squish 
        value = value.gsub("/t","") 
        self.instance_variable_set(attr, value)
      end
    end  
binding.remote_pry
  end

The result is as expected correct:

Now the important part that is not working:

The code is started because I do this:

info = PersonalInfo.new(params["personal_info"])

When it's completed info.last_name is still the bad value:

Problem: Why are the instance_variables not being saved?

More info: - 'rails', '3.2.17' - ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-darwin13.0.2]

回答1:

You will have to call

info.valid?

in order to trigger the validation hook if you are not saving info directly (which will trigger it implicitly).