0

我有一个时间间隔内具有虚拟属性的模型:

attr_accessible :description, :time_end, :time_start, :duration
belongs_to :timesheet

def duration
  if attribute_present?("time_start") and attribute_present?("time_end")
    ChronicDuration.output(self.time_end - self.time_start) 
  else
    ChronicDuration.output(0)
  end
end

def duration=(d)
  self.time_end = self.time_start + d
end

但是,在创建新对象时,Rails 会尝试在启动前设置持续时间,从而导致错误。如何确保在开始设置持续时间?

错误:

undefined method `+' for nil:NilClass

参数:

{"utf8"=>"✓",
 "authenticity_token"=>"dg+CysIxZORyV3cwvD+LdWckFdHgecGDFDBNOip+iKo=",
 "entry"=>{"time_start"=>"now",
 "duration"=>"2h",
 "description"=>""},
 "commit"=>"Create Entry"}
4

2 回答 2

1

1.) 命名属性并不聪明,end因为那是关键字,可能会引起一些麻烦。

2.) 请发布您的参数哈希

于 2012-06-24T09:41:44.127 回答
1

一些东西

  • 值得一读:andvs &&in ruby​​ - http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/
  • 使用attribute_present的一些替代方法?方法

    # opposite of blank? - http://api.rubyonrails.org/classes/Object.html#method-i-present-3F
    if time_start.present? && time_end.present?
    
    # short hand syntax for present?
    if time_start? && time_end?
    

我认为您的问题不在于在 time_start 之前设置了持续时间,假设 time_start 是日期时间或时间数据库类型,请在 rails 控制台中尝试此操作

entry = Entry.new
entry.time_start = "now" 
# => "now"
entry.time_start
# => nil

您正在将字符串传递给时间对象,而 rails / ruby​​ 只是将值设置为 nil。如果 time_end 和 time_start 是字符串,我仍然认为您的代码不会给您想要的结果?

def duration=(d)
  self.time_end = self.time_start + d
end

# params: time_start = "now"
# params: duration = "2h"
# time_end would be: now2h

如果我在设置 time_start 之前对 duration= 运行有误,另一种方法是使用 before_save 回调

class Entry < ActiveRecord::Base
  before_save :set_time_end

  attr_accessor :duration
  attr_accessible :description, :time_end, :time_start, :duration

  belongs_to :timesheet

  def duration
    if time_start? && time_end?
      ChronicDuration.output(self.time_end - self.time_start) 
    else
      ChronicDuration.output(0)
    end
  end

  def set_time_end
    return nil if time_start.blank?
    self.time_end = self.time_start + self.duration
  end
end
于 2012-06-24T18:33:18.213 回答