4

日付「1985 年 3 月 20 日」を「誕生日」というテキスト フィールドに入力し、列タイプ「日付」のデータベース フィールドに挿入しようとしています。

と入力する10/20/1985と「誕生日が無効です」というエラーが表示されますが、入力する20/10/1985と問題なく動作します。

私が読んでいるすべてのドキュメントから、慢性は '10/20/1985' を mm/dd/yyyy として解析する必要がありますが、dd/mm/yyyy として解析しているようです。

日付を mm/dd/yyyy として解析するにはどうすればよいですか?

/models/user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:login]

  # Virtual attribute for authenticating by either username or email
  # This is in addition to a real persisted field like 'username'
  attr_accessor :login

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :login, :first_name, :last_name, :home_phone, :cell_phone, :work_phone, :birthday, :home_address, :work_address, :position, :company

  validate :birthday_is_date
  validate :position, :presence => true

  require 'chronic'

  # validate the birthday format
  def birthday_is_date 
    errors.add(:birthday, "is invalid") unless Chronic.parse(birthday)
  end

  # validates email or username when logging in
  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
    else
      where(conditions).first
    end
  end

end
4

2 に答える 2

3

値がデータベースに日付として保存されている場合、Railsは割り当て時に文字列からRuby日付に値を強制します。私はそれがおそらく組み込みのDate.parse方法(ドキュメント)を使用していると思います:

Date.parse "2012-10-20"
# => #<Date 2012-10-20 ...>

Date.parse "20-10-2012"
# => #<Date 2012-10-20 ...>

Date.parse "10-20-2012"
# => ArgumentError: invalid date

この場合、強制を回避し、Chronicで解析するための生の文字列を手に入れたいと考えています。これは、仮想属性の理想的なユースケースです。あなたがそれをすることができるいくつかの方法があります、このような何かがあなたを始めるはずです

class User < ActiveRecord::Base
  validate :birthday_is_date

  # an explicit implementation
  def birthday_string
    if @birthday_string
      @birthday_string
    elsif birthday.present?
      birthday.strftime("%d-%m-%Y")
    else
      ""
    end
  end

  # a shorter implementation
  def birthday_string
    @birthday_string || birthday.try(:strftime, "%d-%m-%Y")
  end

  def birthday_string=(value)
    @birthday_string = value
    self.birthday = parse_birthday
  end

  private

  def birthday_is_date
    errors.add(:birthday_string, "is invalid") unless parse_birthday
  end

  def parse_birthday
    Chronic.parse(birthday_string)
  end
end

そしてbirthday_string、の代わりにフォームで使用しますbirthday

于 2012-12-27T13:50:28.260 に答える
1

どちらも私にとってはうまくいきます。おそらく更新が必要です。

また:

Chronic.parse '2/10/1985'
#=> 1985-02-10 12:00:00 +0800
Chronic.parse '2/10/1985', :endian_precedence => :little
#=> 1985-10-02 12:00:00 +0800
于 2012-11-09T04:55:21.423 に答える