我目前正在尝试使用日期输入进行自定义验证,但不幸的是,它似乎不起作用。
应用程序中有两个页面,索引页面和搜索页面。索引页内有一个输入日期的文本字段。我正在使用Chronic gem它将文本解析为日期。如果日期无效,Chronic 将返回 nil。如果有效,它将重定向到搜索页面并显示日期。
到目前为止我编写的代码似乎无法正常工作,但我想要实现的是..
1) 验证 Chronic 不会返回 nil
2) 验证该日期大于今天的日期
请注意,我没有使用数据库,我只是希望能够在没有 ActiveRecord 的情况下验证输入的日期。如果有人可以帮助我解决这个问题,我将不胜感激。
views/main/index.html.erb
<%= form_tag({controller: "main", action: "search"}, method: "get") do %>
<%= label_tag(:q, "Enter Date:") %>
<%= text_field_tag(:q) %>
<%= submit_tag "Explore", name: nil %>
<% end %>
views/main/search.html.erb
<%= @show_date %>
main_controller.rb
def search
passed_info = Main.new
if passed_info.valid_date?
@show_date = passed_info
else
flash[:error] = "Please enter correct date!"
render :index => 'new'
end
end
models/main.rb
class Main
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :q
validates_presence_of :q
def initialize(params={})
params.each do |attr, value|
self.public_send("#{attr}=", value)
end if params
end
def persisted?
false
end
def valid_date?
require 'chronic'
if Chronic.parse(q).nil? || Chronic.parse(q) < Time.today
errors.add(:q, "is missing or invalid")
end
end
end
编辑:
这就是问题所在......
本地主机:3000
然后它重定向到..
localhost:3000/main/search?utf8=%E2%9C%93&q=invalid+date+test
没有验证,没有日期,什么都没有..
最佳答案
问题
对返回值要更加小心。当您尝试使用 if valid_date?
保护 Controller 时,您所做的就是检查 valid_date?
是否返回 false。如果解析失败,返回值是errors.add
的输出,而errors.add
的输出又是Array#<<的输出。 。相应地,输出不是 nil
或 false
,因此它的计算结果为 true,因此 if
子句通过并且您继续前进。
潜在的解决方案
您可能想让Rails Validation Framework为你做更多的工作。不要将 valid_date?
视为 Controller 调用的公共(public)方法,而是调用由 ActiveModel::Validations
添加的 valid?
方法。 valid?
将返回一个 bool 值,基于是否所有模型验证都通过。因此,您将像 Rails Way 一样,在 Controller 中调用 if model_instance.valid?
。
这让您只需在模型中编写验证器方法来表达您要编写的逻辑。现在,您在一个方法中拥有日期的所有验证逻辑,并带有一条错误消息。相反,您可以放置两个方法,这会添加更多描述性的单独错误方法。
class YourClass
include ActiveModel::Validations
validate :date_is_valid
validate :date_not_before_today
private
def date_is_valid
if Chronic.parse(q).nil?
errors.add(:q, "Date is invalid")
end
end
def date_not_before_today
if Chronic.parse(q) < Date.today
errors.add(:q, "Date cannot be before today")
end
end
end
关于ruby-on-rails - rails : Custom validations using ActiveModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31011248/