虚拟属性验证始终失败

时间:2014-02-03 07:01:34

标签: ruby-on-rails ruby

我正在将一个日期时间列(是的,我将'datetime'命名为......可能太令人困惑)分为两个虚拟属性date_fieldtime_field

然后使用此SO answer我在before_save回调中重新组合这两个。

但是,现在验证始终会因“不能为空”而失败,无论我是否填写了date_fieldtime_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的正确格式吗?

2 个答案:

答案 0 :(得分:2)

我能看到的问题是:


未设置

before_save在验证后运行before_validation验证之前运行

我看到你正在使用Ruby setters & writers来创建虚拟属性。但是,只有date_field存在时,您的time_fielddatetime制定者才会投放

在您的代码中,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