2012-03-31 94 views
1

编辑:如果下面的问题看起来有点'广泛',摘要是我只想在我的模型中结合一个日期字段和一个可选时间字段纯粹是为了目的验证它使用日期验证程序,但我无法让我的测试正确地失败,当我传递一个字符串作为时间。验证日期和时间字段一起在轨道模型


编辑2:既然我仍然在努力找到一种方式加入Date对象进行验证的目的,时间对象,然后我想,如果我可以验证该时间值是一个Time对象使用is_a?(Time)(而不是一个无效的字符串),但似乎并没有工作,我想知道是否因为Time mention with this method(但我不太了解它足以知道是否导致问题或不。

我也想知道to_time method是否可以帮助我检查是否有Time对象,但我不知道如何。

希望有人可以建议如何加入Date对象与Time对象为验证的目的,或至少告诉我如何我可以检查提交的时间值是一个Time对象,而不是一个无效的字符串或东西。


编辑3:我刚刚试过以下基于另一个答案,我发现,但它仍然没有抱怨在测试“无效”的字符串:

validate :start_time_is_time?, :if => "start_time.present?" 

def start_time_is_time? 
    unless start_time.is_a?(Time) || ((Time.parse(start_time) rescue ArgumentError) == ArgumentError) 
    errors.add(:start_time, 'must be a valid time') 
    end 
end 

有为什么字符串可能会被视为有效的Time


我有类似Trying to set a variable in before_validation but it isn't working与使用日历来选择日期和下拉菜单选择时间图的图。我尝试将其应用于我的模型,但由于我对ruby有点新,并且无法填补答案留下的空白,所以无法实现它。

我的模型有start_date和start_time字段。

我需要组合这两个字段,以便我可以将它们一起验证为datetime(使用date_validator gem),而不必单独验证日期和时间,尽管它们将作为单独的字段放入数据库中,除非有人能够说服我,否则(尽管我已经与他们分开做了很多,所以不想改变这一点)。

必须提交日期,但时间字段是可选的。

从另一个问题看来,我需要一个before_validation方法,可以根据需要将2个字段组合成一个虚拟字段,然后我可以使用date_validator gem进行验证。

编辑:原来的错误已经纠正了感谢RyanJM,但我仍然无法让测试通过正确。以下是目前的比赛状态。

这里是我的欣欣模型的基础知识,现在:

class Showtime < ActiveRecord::Base 

    attr_accessible :start_date, :start_time 

    attr_accessor :starting_at, :starting_time 

    belongs_to :performance 

    before_validation :construct_starting_at 

    validates :start_date, :presence => true, :date => { :after_or_equal_to => Proc.new { Date.today } } 
    validates :starting_at, :date => { :after_or_equal_to => Proc.new { Time.now } }, :if => "start_date.present? && start_time.present?" 

    def construct_starting_at 
    if start_date.present? && start_time.present? 
     self.starting_time = self.start_time.strftime("%T") 
     self.starting_at = DateTime.strptime("#{start_date} #{starting_time}", "%F %T") 
    end 
    end 

end 

在情况下,它是必需的,这里的基础知识/性能模型的相关部分:

class Performance < ActiveRecord::Base 

    has_many :showtimes, :dependent => :delete_all 
    accepts_nested_attributes_for :showtimes, :allow_destroy => true, :reject_if => lambda { |a| a[:start_date].blank? } 

end 

下面是失败的测试:

require 'spec_helper' 

describe Showtime do 

    before(:each) do 
    @attr = { 
     :name => "Performance 1", 
     :showtimes_attributes => { 
       "0" => { 
        :start_date => Date.today+15.days, 
        :start_time => Time.now 
       } 
     } 
    } 
    end 

    it "should test that the start time is a valid time if it exists" do 
    @attr_invalid = { 
     "0" => { 
      :start_date => Date.today+15.days, 
      :start_time => "invalid" 
     } 
    } 
    invalid = Performance.create(@attr.merge(:showtimes_attributes => @attr_invalid)) 
    invalid.should_not be_valid 
    end 

end 

希望我没有在上面的代码中打破任何东西,只是为了显示ne子宫颈部位。

+0

它是如何在实际START_TIME在数据库中定义的? 是否将start_date定义为数据库中的日期时间? – RadBrad 2012-03-31 23:06:44

+0

'start_date'被定义为'date','start_time'被定义为'time'。我将它们保存为独立的字段,以便'start_time'可以是可选的。 – user1116573 2012-04-03 12:41:59

+0

如果start_time是可选的,那么当你准备设置starting_at时,检查它是什么?你可能需要两个案件吗?一个是当它在那里,一个是当它不在?在我的情况下,starting_at是我保存到数据库的对象。你如何声明变量? – RyanJM 2012-04-05 21:03:10

回答

0

我还没有使用date_validator宝石,但做这种事情很好,也似乎更积极维护。

+0

感谢您的回复Thilo。在移至date_validator gem之前,我尝试使用该宝石。我需要允许空白,并且似乎有一个validates_timeliness的缺陷,允许将它应用验证的字段留空。 date_validator gem也似乎更简单一些。 Date_validator似乎没有验证时间,所以我试图合并我的日期和我的时间来得到我可以验证的日期时间。 – user1116573 2012-04-14 15:35:51