在POST / PUT之前将时间(MM:SS)转换为float(秒)到数据库

时间:2013-03-04 13:34:02

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2

我希望用户能够选择或输入一个时间(例如:“你早上花多长时间刷牙?”)以及'创建'或'更新'动作,我想在发布/放入数据库之前将时间转换为浮点数秒。

我现在在模块中有方法(试图学习如何使用模块),但我不确定它是否适合这种情况......

View for Float-to-Time(作品)

<%= MyModule.float_to_time(task.task_length) %>

模块

module MyModule

  def self.float_to_time(secs)       # task.task_length (view)
     ...
     ...
  end

  def self.time_to_float(tim)        # :task_length (controller)
     m = tim.strftime("%M").to_f
     s = tim.strftime("%S.%2N").to_f
     t = ((m*60) + s)
     return t.round(2)
  end

end

控制器

def create
  # "time_to_float" (Convert task_time to seconds float)
  # Create new task after conversion
  @task = Task.new(params[:task])

  respond_to do |format|
    if @task.save
      format.html { redirect_to @task, notice: 'Task was successfully created.' }
      format.json { render json: @event, status: :created, location: @task }
    else
      format.html { render action: "new" }
      format.json { render json: @task.errors, status: :unprocessable_entity }
    end
  end
end

如何在发布(或放入)db之前进行转换?

另外,我应该将这些方法移到application_controller,还是我的模块好吗?

- 感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

对我而言,这似乎是模型的工作,而不是控制器。该模型应关注数据的存储方式,并酌情转换数据类型。

由于您正在尝试学习如何使用模块,因此可以将这些方法作为实例方法保存在模块中,并将它们混合到模型类中:

module TimeConversions
  def time_to_float(time)
    # ...
  end

  def float_to_time(seconds)
    # ...
  end
end

class Task
  extend TimeConversions
  before_save :convert_length

  # ...

private

  def convert_length
    self.length = self.class.time_to_float(length) if length.to_s.include?(':')
  end
end

然后你仍然可以在视图中使用float_to_time

<%= Task.float_to_time(task.length) %>

您可能会在before_save过滤器中执行更复杂的操作,但这可能会为您提供一些想法。

答案 1 :(得分:1)

我认为你正在寻找ActiveRecord Callback

在这种情况下,您可以使用以下内容:

class Task < ActiveRecord::Base
  before_save :convert_task_length_to_float

  def convert_task_length_to_float
    # do the conversion. set `self.task_float =` to update the value that will be saved
  end
end

before_save回调将在Task保存到数据库之前调用。

答案 2 :(得分:1)

此外,您可以覆盖task_length访问器的setter和getter。像这样(在任务模型中):

class Task < ActiveRecord::Base

  def task_length=(tim)
    m = tim.strftime("%M").to_f
    s = tim.strftime("%S.%2N").to_f
    t = ((m*60) + s)
    write_attribute(:task_length, t.round(2))
  end

  def task_length_to_time
    tl = read_attribute(:task_length)
    # ... float-to-time stuff
  end
end

然后在视图<%= task.task_length_to_time %>中使用它。如果您需要浮动,请使用task.task_length