我有一个时间间隔为虚拟属性的模型:
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
PARAMS:
{"utf8"=>"✓",
"authenticity_token"=>"dg+CysIxZORyV3cwvD+LdWckFdHgecGDFDBNOip+iKo=",
"entry"=>{"time_start"=>"now",
"duration"=>"2h",
"description"=>""},
"commit"=>"Create Entry"}
答案 0 :(得分:1)
1。)命名属性end
并不聪明,因为这是一个关键字,可能会造成一些麻烦。
2。)请发布您的参数哈希
答案 1 :(得分:1)
一些事情
and
vs &&
红宝石 - 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是datetime或time数据库类型 在rails console中试试这个
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之前运行持续时间=错误,那么使用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