Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在验证之前,通过自我属性进行循环以进行修改_Ruby On Rails_Validation_Rails Activerecord - Fatal编程技术网

Ruby on rails 在验证之前,通过自我属性进行循环以进行修改

Ruby on rails 在验证之前,通过自我属性进行循环以进行修改,ruby-on-rails,validation,rails-activerecord,Ruby On Rails,Validation,Rails Activerecord,我在验证前创建了一个简单的: before_validation :strip_tabs def strip_tabs end 在我的类中,我想循环遍历我的所有属性,并从每个值中删除制表符。我在SO上找到的大多数帖子都是希望设置1个属性的人。但我想编辑我所有的值 问题: 如何循环模型的所有自属性并对其进行编辑 朋友建议这样做,但内容列名称不存在: self.content_column_names.each {|n| self[n] = self[n].squish} cl

我在验证前创建了一个简单的:

  before_validation :strip_tabs

  def strip_tabs

  end
在我的类中,我想循环遍历我的所有属性,并从每个值中删除制表符。我在SO上找到的大多数帖子都是希望设置1个属性的人。但我想编辑我所有的值

问题: 如何循环模型的所有自属性并对其进行编辑

朋友建议这样做,但内容列名称不存在:

self.content_column_names.each {|n| self[n] = self[n].squish} 
class PersonalInfo
  include ActiveModel::Validations
  include ActiveModel::Validations::Callbacks
  extend ActiveModel::Translation
  extend ActiveModel::Callbacks
  include Sappable
  require 'ext/string'

  attr_accessor \
    :first_name, :middle_name, :last_name,:birthdate,:sex,
    :telephone,:street,:house_number,:city,:postal_code,:country,
    :e_mail, :nationality, :salutation, :com_lang

  validates :e_mail, :email => {:strict_mode => true}
  validate :validate_telephone_number
  validate :age_is_min_17?
    before_validation :strip_tabs

    def strip_tabs
      binding.remote_pry
    end

  def age_is_min_17?
    birthdate_visible =  PersonalField.not_hidden.find_by_name "BIRTHDATE"
    if birthdate_visible && birthdate && birthdate > (Date.current - 17.years)
      @errors.add(:birthdate, I18n.t("apply.errors.birthdate"))
    end
  end

  def validate_telephone_number
    telephone_visible = PersonalField.not_hidden.find_by_name "TELEPHONE"
    telephone_current = telephone.dup

    if telephone_visible &&  telephone_current && !telephone_current.empty?
      if telephone_current[0] == '+' || telephone_current[0] == '0'
        telephone_current[0]  = ''
        @errors.add(:telephone,  I18n.t("apply.errors.telephone")) if !telephone_current.is_number?
      else
        @errors.add(:telephone,  I18n.t("apply.errors.telephone"))
      end
    end
  end

  def initialize(hash)
    simple_attributes = [:first_name, :middle_name, :last_name,:birthdate,:sex,
                         :telephone,:street,:house_number,:city,:postal_code,:country,
                         :e_mail, :nationality, :salutation, :com_lang]
    simple_attributes.each do |attr|
      set_attr_from_json(attr, hash)
    end

    set_attr_from_json(:birthdate, hash) {|date| Date.parse(date) rescue nil}
  end
end
更新1:更多代码:

self.content_column_names.each {|n| self[n] = self[n].squish} 
class PersonalInfo
  include ActiveModel::Validations
  include ActiveModel::Validations::Callbacks
  extend ActiveModel::Translation
  extend ActiveModel::Callbacks
  include Sappable
  require 'ext/string'

  attr_accessor \
    :first_name, :middle_name, :last_name,:birthdate,:sex,
    :telephone,:street,:house_number,:city,:postal_code,:country,
    :e_mail, :nationality, :salutation, :com_lang

  validates :e_mail, :email => {:strict_mode => true}
  validate :validate_telephone_number
  validate :age_is_min_17?
    before_validation :strip_tabs

    def strip_tabs
      binding.remote_pry
    end

  def age_is_min_17?
    birthdate_visible =  PersonalField.not_hidden.find_by_name "BIRTHDATE"
    if birthdate_visible && birthdate && birthdate > (Date.current - 17.years)
      @errors.add(:birthdate, I18n.t("apply.errors.birthdate"))
    end
  end

  def validate_telephone_number
    telephone_visible = PersonalField.not_hidden.find_by_name "TELEPHONE"
    telephone_current = telephone.dup

    if telephone_visible &&  telephone_current && !telephone_current.empty?
      if telephone_current[0] == '+' || telephone_current[0] == '0'
        telephone_current[0]  = ''
        @errors.add(:telephone,  I18n.t("apply.errors.telephone")) if !telephone_current.is_number?
      else
        @errors.add(:telephone,  I18n.t("apply.errors.telephone"))
      end
    end
  end

  def initialize(hash)
    simple_attributes = [:first_name, :middle_name, :last_name,:birthdate,:sex,
                         :telephone,:street,:house_number,:city,:postal_code,:country,
                         :e_mail, :nationality, :salutation, :com_lang]
    simple_attributes.each do |attr|
      set_attr_from_json(attr, hash)
    end

    set_attr_from_json(:birthdate, hash) {|date| Date.parse(date) rescue nil}
  end
end
更新2:Rails版本:
我正在使用Rails“3.2.17”

您可以执行以下操作:

before_validation :strip_tabs

def strip_tabs
  self.attributes.map do |column, value| 
    self[column] = value.squish.presence
  end
end
def strip_tabs
  self.instance_variables.map do |attr|
    value = self.instance_variable_get(attr)
    value = value.squish if value.kind_of?(String)
    self.instance_variable_set(attr, value)
  end
end
但是我认为
.squish
创建、更新、id
、。。。因为它们不是绳子

def strip_tabs
  self.attributes.map do |column, value|
    self[column] = value.kind_of?(String) ? value.squish.presence : value
  end
end

由于您的类不是Rails模型(ActiveRecord::Base),因此可以执行以下操作:

before_validation :strip_tabs

def strip_tabs
  self.attributes.map do |column, value| 
    self[column] = value.squish.presence
  end
end
def strip_tabs
  self.instance_variables.map do |attr|
    value = self.instance_variable_get(attr)
    value = value.squish if value.kind_of?(String)
    self.instance_variable_set(attr, value)
  end
end
这应该行得通

def strip_tabs
    self.attributes.each do |attr_name, attr_value|
        modified_value = ... # calculate your modified value here
        self.write_attribute attr_name, modified_value
    end
end

因为它不是ActiveRecord模型,所以您没有
属性
列名
,但在
初始化
函数中已经有了属性名数组。我建议将其设置为常数,以便您可以在整个模型中访问它:

class PersonalInfo
  include ActiveModel::Validations
  include ActiveModel::Validations::Callbacks
  extend ActiveModel::Translation
  extend ActiveModel::Callbacks
  include Sappable
  require 'ext/string'

  SIMPLE_ATTRIBUTES = [:first_name, :middle_name, :last_name,:birthdate,:sex,
                     :telephone,:street,:house_number,:city,:postal_code,:country,
                     :e_mail, :nationality, :salutation, :com_lang]

  attr_accessor *SIMPLE_ATTRIBUTES

  before_validation :strip_tabs

  def strip_tabs
    SIMPLE_ATTRIBUTES.each{ |attr| self[attr] = self[attr].squish }
  end

  ...

  def initialize(hash)
    SIMPLE_ATTRIBUTES.each do |attr|
      set_attr_from_json(attr, hash)
    end

    set_attr_from_json(:birthdate, hash) {|date| Date.parse(date) rescue nil}
  end
end

NoMethodError:undefined method
attributes'for#from(pry):2:在
strip_tabs'中,我将在一秒钟内发布更多代码。我正在通过pry测试这一点,您使用的是哪一版本的rails?我正在使用rails'3.2.17',您需要在模型定义中扩展ActiveRecord::Base感谢您的回答,我感谢您提供的每一点智慧。NoMethodError:undefined method
attributes'for#from(pry):2:在
strip_tabs'中,由于某些奇怪的原因self.attributes不起作用。我正在通过pry对此进行测试。这是因为您的对象不是来自
ActiveRecord::Base
的模型,而是一个简单的类。您建议如何让它在这个类中工作?感谢这对我的帮助,我将进一步编辑此主题,因为这不是一个模型。
self.instance\u variables
只返回设置的变量,例如,
Car.new(颜色:'red')。实例变量
返回
[:@color]
,但
Car.new(颜色:'red',名称:'Audi')。实例变量
返回
[:@color,:@name]
。所以我想,我认为,让它这样就足够了。设置、处理和“复制”到其他类似乎很繁重。@DaveMongoose,谢谢你的帮助,我会等Yoshiji先生解释“设置、处理和“复制”到其他类”