我正在将一个日期时间列(是的,我将'datetime'命名为......可能太令人困惑)分为两个虚拟属性date_field
和time_field
。
然后使用此SO answer我在before_save
回调中重新组合这两个。
但是,现在验证始终会因“不能为空”而失败,无论我是否填写了date_field
或time_field
这是我的模特:
class SomeModel < ActiveRecord::Base
validates :date_field, :time_field, presence: true
before_save :convert_to_datetime
def date_field
datetime.strftime("%d/%m/%Y") if datetime.present?
end
def time_field
datetime.strftime("%I:%M%p") if datetime.present?
end
def date_field=(date)
@date_field = Date.parse(date).strftime("%Y-%m-%d")
end
def time_field=(time)
@time_field = Time.parse(time).strftime("%H:%M:%S")
end
def convert_to_datetime
self.datetime = DateTime.parse("#{@date_field} #{@time_field}")
end
end
修改
以下是调查后的一些新信息:
1)根据xmpolaris的评论,我尝试@date_field || datetime.present? datetime.strftime("%d/%m/%Y") : nil
,但返回nil
2)我将before_save
替换为before_validation
,这给了我500无效的日期错误。
3)我用byebug检查了这些参数,它们看起来像这样:
(byebug) p params[:date_field]
"2014-02-10"
(byebug) p params[:time_field]
"11:30"
这是Rails的正确格式吗?
答案 0 :(得分:2)
我能看到的问题是:
未设置
before_save
在验证后运行(before_validation
在验证之前运行)
我看到你正在使用Ruby setters & writers来创建虚拟属性。但是,只有date_field
存在时,您的time_field
和datetime
制定者才会投放
在您的代码中,datetime
仅在您的before_save
回调中设置日期时间属性时出现,这意味着您不会为您的二传手提供datetime
我会试试这个:
class SomeModel < ActiveRecord::Base
before_validation :convert_to_datetime
end
虽然可能会有所帮助,但我认为这不会完全有效
答案 1 :(得分:0)
经过一番头痛之后,事实证明我需要更改我的模板...
<input type="text" id="time_field" name="time_field">
到此:
<input type="text" id="time_field" name="lesson[time_field]">
参数甚至没有首先设置。
有谁知道为什么这是必要的?如果可以改变这种行为?
此外,xmpolaris的评论是正确的。还有必要将我的吸气剂改为:
def date_field
@date_field || datetime ? datetime.strftime("%d/%m/%Y") : nil
end
def time_field
@time_field || datetime ? datetime.strftime("%d/%m/%Y") : nil
end