Ruby on rails Rails:验证是否选择了日期\u select中的所有字段,但仍将:prompt设置为true
当使用railsdate_select with:prompt=>true时,在提交表单时,如果没有选择所有字段,我会看到一些非常奇怪的行为。例如 提交选中了“一月”的表单,但保留在默认提示下的“日期”和“年份”字段将导致在0001年1月1日传递给模型验证。如果验证失败并再次呈现表单,则仍然选择1月(正确),但日期设置为1(错误)。如果提交表单时只选择了年份,则月和日都将设置为1Ruby on rails Rails:验证是否选择了日期\u select中的所有字段,但仍将:prompt设置为true,ruby-on-rails,Ruby On Rails,当使用railsdate_select with:prompt=>true时,在提交表单时,如果没有选择所有字段,我会看到一些非常奇怪的行为。例如 提交选中了“一月”的表单,但保留在默认提示下的“日期”和“年份”字段将导致在0001年1月1日传递给模型验证。如果验证失败并再次呈现表单,则仍然选择1月(正确),但日期设置为1(错误)。如果提交表单时只选择了年份,则月和日都将设置为1 这是一个非常奇怪的行为-有人能给我一个解决方法吗?这个问题与多参数赋值有关。基本上,您希望将三个值存储到一个属性中(
这是一个非常奇怪的行为-有人能给我一个解决方法吗?这个问题与多参数赋值有关。基本上,您希望将三个值存储到一个属性中(即写入)。所选日期将其作为
{'writed_at(1)=>'2009','writed_at(2)=>'5','writed_at(3)=>'27}
发送给控制器。活动记录将这三个值打包成一个字符串,并用它初始化一个新的日期对象
问题开始于这样一个事实,即当您尝试使用无效日期来实例化Date时,Date会引发异常,例如,Date.new(2009,0,1)
。Rails捕获该错误并实例化一个时间对象。Rails中支持时区的Time类具有各种各样的魔力,可以使它不使用无效数据。这会让你的一天变成一天
在此过程中,active record会释放原始值散列,因为它将写入的内容打包到一个数组中,并试图从中创建日期或时间对象。这就是为什么表单不能再使用writed\u at\u before\u time\u cast
方法访问它的原因
解决方法是在模型中添加六种方法:writed\u at_year
,writed\u at_year=
,以及writed\u at_year\u before\u type\u cast
(用于年、月和日)。验证前的过滤器可以重建日期并将其写入写入
class Event < ActiveRecord::Base
before_validation :reconstruct_written_at
def written_at_year=(year)
@written_at_year_before_type_cast = year
end
def written_at_year
written_at_year_before_type_cast || written_at.year
end
def written_at_year_before_type_cast
@written_at_year_before_type_cast
end
private
def reconstruct_written_at
written_at = Date.new(written_at_year, written_at_month, written_at_day)
rescue ArgumentError
written_at = nil
end
end
class事件
一个代码示例可能会帮助我们帮助您。谢谢-看起来这就是我要找的,但我必须说,对于这样一个简单而常见的功能来说,这简直是太复杂了!我赞成。这太复杂了。您好,在def writed_at_year=(year)或@writed_at_year=year之前,def writed_at_year中的“year”是什么?这不是写于年吗?我真的不明白这部分(