7

在 Rails 中验证结束日期不在开始日期之前以及开始日期在结束日期之后的最佳方法是什么?

我的视图控制器中有这个:

<tr>
    <td><%= f.label text="Starts:" %></td>
    <td><%= f.datetime_select :start_date, :order => [:day, :month, :year]%></td>
</tr>
<tr>
    <td><%= f.label text="Ends:" %></td>
    <td><%= f.datetime_select :end_date,:order => [:day, :month, :year]</td>
</tr>

我希望它能够提供某种弹出窗口,并带有有意义的消息。

我想做一个通用方法,它接受两个参数,开始日期和结束日期,然后我可以在我的 viewcontroller 中调用它;fx在上面的代码中。或者,我需要改用 jQuery 吗?

4

5 回答 5

14

@YaBoyQuy 客户端验证可以工作并避免对服务器造成冲击......

问题也是关于 end_date 在开始之后,所以验证 - 使用 gem date_validator- 也应该说明

validates :end_date, presence: true, date: { after_or_equal_to:  :start_date}

的建议

on: :create

end_date 验证不正确;从逻辑上讲,这也应该在编辑时运行。

我在简洁语法的基础上投了赞成票。

于 2014-03-27T08:18:47.797 回答
6

干净利落(并且在控制之下?)

我发现这是最清楚的阅读:

在您的模型中

validates_presence_of :start_date, :end_date

validate :end_date_is_after_start_date


#######
private
#######

def end_date_is_after_start_date
  return if end_date.blank? || start_date.blank?

  if end_date < start_date
    errors.add(:end_date, "cannot be before the start date") 
  end 
end
于 2014-08-29T16:47:36.257 回答
5

避免客户端验证,因为它只验证客户端......使用内置的 rails 验证器。

  validates :start_date, presence: true, date: { after_or_equal_to: Proc.new { Date.today }, message: "must be at least #{(Date.today + 1).to_s}" }, on: :create
  validates :end_date, presence: true
于 2012-08-31T16:41:29.103 回答
2

要使用你的validates :dt_end, :date => {:after_or_equal_to => :dt_start},你需要有一个DateValidator这样的:


class DateValidator > ActiveModel::Validator
  def validate(record)
    the_end = record.dt_end
    the_start = record.dt_start
    if the_end.present?
      if the_end < the_start
        record.errors[:dt_end] << "The end date can't be before the start date. Pick a date after #{the_start}"
      end
    end
  end
end
于 2014-12-04T13:47:24.707 回答
2

如果您想要客户端验证,请使用 jQuery。

或者在 Rails 中,为了验证服务器端,我猜你可以创建自己的?

def date_validation
  if self[:end_date] < self[:start_date]
    errors[:end_date] << "Error message"
    return false
  else
    return true
  end
end
于 2012-08-30T14:30:38.033 回答