将虚拟属性与超类(STI)中的单个类属性相结合

时间:2013-08-23 21:00:25

标签: ruby-on-rails getter-setter single-table-inheritance virtual-attribute

我正在尝试合并start_date表单中的start hourstart_minuteEvent虚拟属性,以便创建start_datetime属性(它存储在数据库中。)

我有(通过STI)几个Event的子类;我们称他们为TrainingSessionWorkSession以及PersonalTime

类的结构如下:

class Event < ActiveRecord::Base
  ...
end

class TrainingSession < Event
  ...
end

class WorkSession < Event
  ...
end

class PersonalTime < Event
  ...
end

event.rb的相关部分:

class Event < ActiveRecord::Base
  attr_accessor :start_date, :start_hour, :start_minute

  validates :start_datetime, :presence => true

  before_validation :merge_attributes_for_datetime_string

  def merge_attributes_for_datetime_string
    start_datetime_string = "#{ start_date } #{ start_hour }:#{ start_minute }:00"
  end

  def start_datetime=(start_datetime_string)
    self.start_datetime = start_datetime_string
  end

  def start_date
    start_datetime.strftime("%d") if start_datetime?
  end

  def start_hour
    start_datetime.strftime("%H") if start_datetime?
  end

  def start_minute
    start_datetime.strftime("%M") if start_datetime?
  end
end

......以及events_controller.rb

  def create
    @event = Event.new(event_params)
    if @event.save
      redirect_to :root, :flash => { :success => "Event added." }
    else
      redirect_to :back, :flash => { :notice => "There was an error creating the event." }
    end
  end

  private

  def event_params
    params.require(:event).permit(
      :type,
      :start_datetime,
      :start_date,
      :start_hour,
      :start_minute,
      ...
    )
  end

  def training_session_params
    params.require(:training_session).permit(
      ...
    )
  end

  def work_session_params
    params.require(:work_session).permit(
      ...
    )
  end

  def personal_time_params
    params.require(:personal_time).permit(
      ...
    )
  end

我已经在我的服务器日志中验证了从表单发送了正确的参数:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"<TOKEN HERE>=", "event"=>{"start_date" => "2013-08-23", "start_hour"=>"15", "start_minute"=>"00", "type"=>"PersonalTime"}, "commit"=>"Add Personal Time"}

然而,每当我尝试创建一个事件(任何类型)时,我都会收到通知There was an error creating the event.(根据我的创建方法)。如果我发表评论validates :start_datetime,则会创建活动,但start_datetimenil

这必须意味着start_datetime字符串未与虚拟属性正确合并,但我无法弄清楚原因。

我在这里缺少什么?有没有更好的方法来设置start_datetime

1 个答案:

答案 0 :(得分:0)

根据您发布的内容,我看不到您调用start_datetime方法的位置。

您可以按照以下方式在start_datetime方法中进行合并,而不是定义新方法:

before_validation :merge_attributes_for_datetime_string

def merge_attributes_for_datetime_string
  self.start_datetime = "#{ start_date } #{ start_hour }:#{ start_minute }:00"
end