0

I have a simple table for storing users accounts information (emails and passwords) with two additional columns:

  1. is_active - says if user account is enable or disabled - the column type is boolean and in the context of DB2 it is mapped with decimal(1)
  2. registration_date - says when the user was created - the column type is datetime and in the context ofDB2 it is mapped with datetime

As this fields will not be set by the user, I have deleted their inputs from the users _form.

I want to populated this fields in my users controller as follows:

def create

   @security_user = SecurityUser.new(params[:security_user])

   @security_user.is_active = 0
   @security_user.registration_date = DateTime.now

  ...

end

But I can not pass the validations that I have in the model. They looks like:

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

where the 'lib/date_format_validator' looks like follows:

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

What I am doing wrong?

EDIT: The screenshot below displays the errors:

enter image description here

EDIT2: Sam Ruby's answer helps me to finish with something like this for my custom validator method:

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

and to transform the validates method for the is_active column as follows:

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

because as it is said in the official documentation:

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] }.
4

1 回答 1

1

问题是您试图验证 ActiveRecord 对象,就好像列是字符串类型一样。但是由于您已将列定义为布尔值和日期时间,因此您将验证的类型将是 TrueClass、FalseClass 或 ActiveSupport::TimeWithZone。

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

true永远是01

DateTime.parse(DateTime.now)总会提高ArgumentError

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

于 2013-04-21T13:39:17.573 回答