使用真实属性设置虚拟属性

时间:2012-06-24 06:32:00

标签: ruby-on-rails model

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

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"}

2 个答案:

答案 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