无法在“create”方法中覆盖对象属性

时间:2013-04-21 13:08:51

标签: ruby-on-rails-3 custom-validators

我有一个简单的表格,用于存储用户帐户信息(电子邮件和密码)以及另外两列:

  1. is_active - 表示启用或禁用用户帐户 - 列 type是 boolean ,并在DB2的上下文中映射 十进制(1)
  2. registration_date - 表示创建用户的时间 - 列 type是 datetime ,在它的上下文中,它是映射的 日期时间
  3. 由于用户不会设置此字段,我已从用户_form中删除了他们的输入。

    我想在我的用户控制器中填写此字段,如下所示:

    def create
    
       @security_user = SecurityUser.new(params[:security_user])
    
       @security_user.is_active = 0
       @security_user.registration_date = DateTime.now
    
      ...
    
    end
    

    但我无法通过模型中的验证。他们看起来像:

    class SecurityUser < ActiveRecord::Base
    
      # Loading custom validators
      require 'lib/date_format_validator'
      ...
    
      # Accessible columns
      ...
    
      # Relationships
      ...
    
      # Validations
      validates :is_active, inclusion: { in: 0..1, message: "only '0' and '1' allowed"}, presence: true
      validates :registration_date, date_format:true , presence: true
    
    end
    

    其中'lib / date_format_validator'如下所示:

    class DateFormatValidator < ActiveModel::EachValidator
    
      def validate_each(object, attribute, value)
        if (DateTime.parse(value) rescue ArgumentError) == ArgumentError
          object.errors[attribute] << (options[:message] || "is not valid datetime")
        end
      end
    
    end
    

    我做错了什么?

    编辑:下面的屏幕截图显示错误:

    enter image description here

    EDIT2:Sam Ruby的回答帮助我完成了这样的定制验证方法:

    class DateFormatValidator < ActiveModel::EachValidator
    
      def validate_each(object, attribute, value)
        unless value.kind_of? DateTime || (DateTime.parse(value) rescue ArgumentError) != ArgumentError
          object.errors[attribute] << (options[:message] || "is not valid datetime")
        end
      end
    
    end
    

    并转换is_active列的validates方法,如下所示:

    validates :is_active, inclusion: { in: [ true, false ], message: "only 'true' and 'false' allowed"}
    

    因为正如官方文件中所述:

    Since false.blank? is true, if you want to validate the presence of a boolean field you should use validates :field_name, :inclusion => { :in => [true, false] }.
    

1 个答案:

答案 0 :(得分:1)

问题是您正在尝试验证ActiveRecord对象,就好像列是String类型一样。但是,由于您已将列定义为boolean和datetime,因此您将验证的类型为TrueClass,FalseClass或ActiveSupport :: TimeWithZone。

换句话说,这些值已经被解析了。

true永远不会是01

DateTime.parse(DateTime.now)将始终提升ArgumentError

如果要验证未解析的值,请在控制器中执行此操作。