0

我希望用户能够选择或输入时间(例如:“您早上刷牙多长时间?”)并且在“创建”或“更新”操作中,我想转换时间在发布/放入数据库之前的几秒钟内浮动。

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

浮动时间查看(作品)

<%= 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

如何在发布(或放置)到数据库之前进行转换?

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

- 谢谢你的帮助。

4

3 回答 3

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过滤器中做一些更复杂的事情,但这也许会给你一些想法。

于 2013-03-04T14:11:25.467 回答
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

于 2013-03-04T14:11:56.513 回答
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如果你需要它在浮动中使用。

于 2013-03-04T14:14:15.040 回答