如果Rails中的日期格式不正确,如何正确显示验证错误?

Dav*_*ave 6 format validation ruby-on-rails dob ruby-on-rails-4

我正在使用Rails 4.2.7.如果用户没有以正确的格式输入他们的出生日期字段,我想抛出验证错误,所以我有

  def update
    @user = current_user
    begin
      @user.dob = Date.strptime(params[:user][:dob], '%m/%d/%Y')
    rescue ArgumentError => ex
    end
    if @user.update_attributes(user_params)
Run Code Online (Sandbox Code Playgroud)

在我看来,我有这个

      <%= f.text_field :dob, :value => (f.object.dob.strftime('%m/%d/%Y') if f.object.dob), :size => "20", :class => 'textField', placeholder: 'MM/DD/YYYY' %>
      <% if @user.errors[:dob] %><%= @user.errors[:dob] %><% end %>
Run Code Online (Sandbox Code Playgroud)

但是,即使有人输入"01-01/1985"之类的日期,上述内容也不会向视图返回验证错误.我需要做什么才能正确返回验证错误?

编辑:根据给出的答案之一,我试过了

@user = current_user
begin
  @user.dob = Date.strptime(params[:user][:dob], '%m/%d/%Y')
rescue ArgumentError => ex
  puts "Setting error." 
  @user.errors.add(:dob, 'The birth date is not in the right format.')
end
if @user.update_attributes(user_params)
  last_page_visited = session[:last_page_visited]
  if !last_page_visited.nil?
    session.delete(:last_page_visited)
  else
    flash[:success] = "Profile updated"
  end
  redirect_to !last_page_visited.nil? ? last_page_visited : url_for(:controller => 'races', :action => 'index') and return
else
  render 'edit'
end
Run Code Online (Sandbox Code Playgroud)

即使我可以看到调用的"救援"分支,我也没有被引导到我的"渲染'编辑'"块.

Dou*_*oug 3

调用update_attributes会清除您在rescue. 您应该检查是否有错误,如果没有,则继续,如下所示:

@user = current_user
begin
  @user.dob = Date.strptime(params[:user][:dob], '%m/%d/%Y')
rescue ArgumentError => ex
  puts "Setting error." 
  @user.errors.add(:dob, 'The birth date is not in the right format.')
end
if !@user.errors.any? && @user.update_attributes(user_params)
  last_page_visited = session[:last_page_visited]
  if !last_page_visited.nil?
    session.delete(:last_page_visited)
  else
    flash[:success] = "Profile updated"
  end
  redirect_to !last_page_visited.nil? ? last_page_visited : url_for(:controller => 'races', :action => 'index') and return
end

render 'edit'
Run Code Online (Sandbox Code Playgroud)

既然您redirect_to ... and return可以关闭条件,并且如果您做到了这一点,则只需渲染编辑页面即可。

您可能还想向您的用户模型添加简单的验证:

validates :dob, presence: true
Run Code Online (Sandbox Code Playgroud)

如果由于其他不可预见的原因而无法设置 dob,则此操作始终会失败。

要让用户输入的字符串在重新加载时填充字段,您可以为 :dob_string 添加一个访问器到用户模型

attr_accessor :dob_string

def dob_string
  dob.to_s
  @dob_string || dob.strftime('%m/%d/%Y')
end

def dob_string=(dob_s)
  @dob_string = dob_s
  date = Date.strptime(dob_s, '%m/%d/%Y')
  self.dob = date
rescue ArgumentError
  puts "DOB format error"
  errors.add(:dob, 'The birth date is not in the correct format')
end
Run Code Online (Sandbox Code Playgroud)

然后更改表单以设置 :dob_string

<%= form_for @user do |f| %>
  <%= f.text_field :dob_string, :value => f.object.dob_string , :size => "20", :class => 'textField', placeholder: 'MM/DD/YYYY' %>
  <% if @user.errors[:dob] %><%= @user.errors[:dob] %><% end %>
  <%= f.submit %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

并更新控制器以设置 dob_string:

def update
  @user = User.first
  begin
    #@user.dob = Date.strptime(params[:user][:dob], '%m/%d/%Y')
    @user.dob_string = user_params[:dob_string]
  end
  if ! @user.errors.any? && @user.update_attributes(user_params)
    redirect_to url_for(:controller => 'users', :action => 'show') and return
  end
  render 'edit'
end

def user_params
  params.require(:user).permit(:name, :dob_string)
end
Run Code Online (Sandbox Code Playgroud)