转换时间&保存记录前的几分钟到几秒钟

时间:2015-10-21 13:03:33

标签: ruby-on-rails forms model

我仍然是Rails的新手。到目前为止,我的所有表单元素都直接映射到它们的底层Rails模型对应物。在我目前的情况下,虽然这是不可能的。

我的模型有一个event_duration字段,以秒为单位存储持续时间(integer类型)。

在我的表单中,我希望有两个文本字段:hoursminutes。提交表单时,我想将这些值转换为秒,并将结果值存储在模型中。

实现这一目标的最佳方法是什么? (先谢谢你)

3 个答案:

答案 0 :(得分:2)

您可以创建一个' hook'在您的控制器中,在创建/更新记录之前更新$

params

此代码表示您的表单中包含名为class EventsController < ApplicationController before_filter :sanitize_durations_in_params, only: [:create, :update] # ... def sanitize_durations_in_params hours = params[:event].delete(:hours).to_i minutes = params[:event].delete(:minutes).to_i minutes = minutes + hours * 60 seconds = minutes * 60 params[:event][:event_duration] = seconds end end 的输入和另一个名为event[:hours]的输入。如果您已经有一个名为event[:minutes]的输入,那么它将被覆盖。

答案 1 :(得分:1)

您可以在模型中创建虚拟属性:

class Model < ActiveRecord::Base
  attr_reader :hours_event_duration, :minutes_event_duration, :use_diff_event_duration_variables
  before_save :correct_save_event_duration

  def initialize(*args)
    @hours_event_duration = @minutes_event_duration = 0
    @use_diff_event_duration_variables = false
    super
  end

  ... 

  protected

  def correct_save_event_duration
    self.event_duration = @hours_event_duration * 1.hour + @minutes_event_duration * 1.minute if @use_diff_event_duration_variables
  end
end

以你的形式:

f.hidden_field :use_diff_event_duration_variables, true
f.text_field :hours_event_duration
f.text_field :minutes_event_duration

答案 2 :(得分:1)

另一种实现此目的的方法是所谓的表单对象,它本质上是一个“模型”,您可以将其传递给控制器​​,代替您的模型,然后处理表单呈现和持久性。

这样做的好处是你的控制器中不需要任何逻辑,你可以从你的模型中消除讨厌的回调。在处理多个模型时,它们也能很好地摆脱那些accepts_nested_attributes_for陷阱。

它看起来像这样:

# app/forms/event_form.rb
class EventForm
  include ActiveModel::Model
  include ActiveModel::Validations

  attr_accessor :duration_hours, :duration_minutes, ... # Event parameters

  validates ... # Your validations

  def save
    if valid?
      persist!
    else
      false
    end
  end

  private

  def persist!
    event = Event.new(...) # Event parameters
    event.event_duration = ((duration_hours * 60) + duration_minutes) * 60
    event.save
  end
end

通过包含一些ActiveModel模块,您可以借用一些功能,例如从Hash初始化和验证。

在你的控制器中:

# app/controllers/events_controller.rb
def new
  @event = EventForm.new
end

def create
  @event = EventForm.new(event_params).save
end

如果您不想自己动手,也可以使用Gems来创建表单对象,例如reform