简体   繁体   English

在保存记录之前将小时和分钟转换为秒

[英]Convert hours & minutes to seconds before saving a record

I am still very new to Rails. 我对Rails还是很陌生。 Thus far all of my form elements have mapped directly to their underlying Rails model counterparts. 到目前为止,我所有的表单元素都已直接映射到其基础的Rails模型副本。 In my current situation though that isn't possible. 在目前的情况下,这是不可能的。

My model has an event_duration field which stores a duration in seconds ( integer type). 我的模型有一个event_duration字段,该字段存储以秒为单位的持续时间( integer类型)。

In my form though I want to have two text fields: hours and minutes . 在我的表单中,尽管我想要两个文本字段: hoursminutes When the form is submitted I want to convert those values into seconds and store the resulting value in the model. 提交表单后,我想将这些值转换为秒并将结果值存储在模型中。

What is the best way to accomplish this? 做到这一点的最佳方法是什么? (Thank you in advance) (先感谢您)

You can create a 'hook' in your controller to update the params right before the record is created/updated: 您可以在控制器中创建一个“钩子”以在创建/更新记录之前更新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

This code implies that you have an input with name event[:hours] and another one with event[:minutes] in your form. 此代码意味着您在表单中输入了一个名称为event[:hours]的输入,另一个输入是event[:minutes] If you already have an input with name event[:event_duration] , it will be overwriten. 如果您已经有一个名称为event[:event_duration]的输入,它将被覆盖。

You can create virtual attributes in your model: 您可以在模型中创建虚拟属性:

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

And in your form: 并以您的形式:

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

Another way to accomplish this is what's called a Form Object, which is essentially a "mock model" that you pass to your controller in lieu of your model, which then handles form rendering and persistence. 完成此操作的另一种方法是所谓的“表单对象”,它实际上是一个“模拟模型”,您可以将其传递给控制器​​以代替模型,然后由模型处理表单渲染和持久性。

The benefits of this is you don't need any logic in your controllers, and you can eliminate pesky callbacks from your models. 这样做的好处是您不需要控制器中的任何逻辑,并且可以从模型中消除讨厌的回调。 They also work exceptionally well for getting rid of those accepts_nested_attributes_for traps when dealing with multiple models. 当处理多个模型时,它们还可以很好地摆脱那些accepts_nested_attributes_for陷阱。

It can look something like this: 它看起来可能像这样:

# 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

By including some of the ActiveModel modules, you can borrow some functionality, like initializing from a Hash , and validations. 通过包括一些ActiveModel模块,您可以借用一些功能,例如从Hash初始化和验证。

And in your controller: 在您的控制器中:

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

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

There are also Gems that you can use to create form objects, like reform , if you don't want to roll your own. 如果您不想自己动手,也可以使用Gems来创建表单对象,例如Reform

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM