我有一个预约模型,其约会属性为date
,并且具有虚拟属性duration
,表示约会需要多长时间。真实属性booking_end
需要在我的应用程序中引用的Time。但是,为了便于输入,我们使用持续时间而不是选择另一个Time
。字段如下:
def duration
( (booking_end - date) / 1.hour ).round( 2 ) rescue nil
end
def duration=(temp)
if ( true if Float(temp) rescue false )
self.booking_end = time_round(date + temp.to_f.hours, 15.minutes)
else
errors.add(:duration, "must be a number, stated in hours.")
self.booking_end = nil
end
end
当我在创建新记录时引用date
字段时,整个事情都失败了。我收到'nil'错误,因为date尚未初始化。我该如何解决这个问题?其余部分在更新现有记录时有效。
答案 0 :(得分:0)
当您致电 Reservation.new(:date => date,:duration => duration) ActiveRecord :: Base以这种方式分配属性值(请参阅assign_attributes方法):
attributes.each do |k, v|
...
respond_to?("#{k}=") ? send("#{k}="", v)
...
哈希#每个方法在:date 之前访问:duration 键的方式遍历值,因此 date duration = 方法中为零:
ruby-1.8.7-p302 > {:date => Date.today, :duration => 5}.each do |key,value|
ruby-1.8.7-p302 > puts "#{key} = #{value}"
ruby-1.8.7-p302 ?> end
duration = 5
date = 2010-11-17
因此,您必须在初始化后调用 duration = 。
或者您可以重新定义Reservation#initialize以使用:date调用super,然后使用其余参数调用update_attributes。
答案 1 :(得分:0)
我尝试用
初始化模型Reservation.new(params[:reservation][:date])
然后在其上调用update_attributes
。这适用于控制台,但不是。似乎唯一可行的解决方法是从params哈希中剥离持续时间,然后在保存之前将其传回。这看起来真的很愚蠢,而且可能不是正确或Rails做事的方式。使用4行,其中一行就足够了。
duration = params[:reservation][:duration]
params[:reservation].delete('duration')
@reservation = Reservation.new(params[:reservation])
@reservation.duration = duration
# Then go to save, etc.
是否有不同的方法来初始化模型或者可能从模型内部访问属性哈希?