如何在Rails 3中验证日期?为什么验证会看到Date而不是String

时间:2012-07-10 17:58:15

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

我正在尝试编写日期验证程序。我遇到的问题是我的验证器将date_of_birth视为Date对象,但它被设置为String。 (1)为什么在验证适用之前将它看作Date而不是String?(2)我应该怎么做才能让它作为String而不是Date读取它。我遇到的问题是我想接受%m/%d/%Y日期,但是当我在07/05/2010进入时,我将其转换为日期,其中05视为月份而07视为日期。我正在使用Devise,所以我不确定它是否正在对控制器中的日期做些什么,我怀疑。

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :first_name, :last_name, :password, :password_confirmation, :remember_me, :address, :date_of_birth, as: [:default, :admin]
  attr_accessible :active, :role, as: [ :admin ]

  validates_presence_of :email, :first_name, :last_name, :address
  validate :valid_date_of_birth

  def date_of_birth=(date_of_birth)
    Rails.logger.info("set date_of_birth: #{date_of_birth}")
    Rails.logger.info("set date_of_birth class: #{date_of_birth.class}")
    self[:date_of_birth] = date_of_birth
  end

  private
  def valid_date_of_birth
    Rails.logger.info "the date of birth: #{date_of_birth}"
    Rails.logger.info "the date of birth class: #{date_of_birth.class}"
    errors.add(:date_of_birth, 'must be a valid datetime') if ((DateTime.strptime(date_of_birth, "%m/%d/%Y") rescue ArgumentError) == ArgumentError)
  end
end

所以,设置date_of_birth,我得到String。 valid_date_of_birth将其视为Date,这是date_of_birth的数据库类型。我在这里做错了什么让这太复杂了?我唯一的选择是维护一个额外的String字段吗?这是如何工作的?编辑?

1 个答案:

答案 0 :(得分:1)

如果您的 date_of_birth 属性是从参数/从表单设置的 - 那么它将作为字符串进入。问题出现在它被设置为对象的地方 - 它被转换为数据库中数据类型的数据类型。

因此,在创建操作中的 users_controller 中: params [:user] [:date_of_birth] 以字符串形式出现

但是只要将其设置为User对象: @ user.date_of_birth = params [:user] [:date_of_birth] ##它会转换为数据库中的类型(日期类型)。

解决方案: 1)在分配之前验证控制器中的date_of_birth。 2)在分配给User对象之前,为date_of_birth_input定义一个attr_accessor并在模型中进行验证,就像你当前正在做的那样。