Rails 4 - 将datetime转换为单独的日期和时间字段

时间:2013-08-27 09:32:46

标签: ruby-on-rails datetime datepicker ruby-on-rails-4 timepicker

如何将mysql日期时间字段转换为两个表单字段(1)仅限日期,(2)仅限时间,并在表单提交时将两个字段合并回日期时间格式?

这将允许使用以下宝石,但将日期存储在单个日期时间字段中:

gem 'bootstrap-datepicker-rails'
gem 'bootstrap-timepicker-rails'

提前致谢!

4 个答案:

答案 0 :(得分:16)

在@Althaf的帮助下找到解决方案

model.rb 添加了虚拟属性 使用before_save回调转换回日期时间。

before_save :convert_to_datetime

def sched_date_field
  sched_date.strftime("%d/%m/%Y") if sched_date.present?
end 

def sched_time_field
  sched_time.strftime("%I:%M%p") if sched_time.present?
end

def sched_date_field=(date)
  # Change back to datetime friendly format
  @sched_date_field = Date.parse(date).strftime("%Y-%m-%d")
end

def sched_time_field=(time)
  # Change back to datetime friendly format
  @sched_time_field = Time.parse(time).strftime("%H:%M:%S")
end

def convert_to_datetime
  self.sched_time = DateTime.parse("#{@sched_date_field} #{@sched_time_field}")
end

使用Rails 4,需要将sched_date_field和sched_time_field添加到 controller.rb中的强参数

以下是 _form.html.erb

中的字段
<%= f.label :sched_date_field, "Scheduled Date" %>
<%= f.text_field :sched_date_field, :class => "datepicker" %>

<%= f.label :sched_time_field, "Scheduled Time" %>
<%= f.text_field :sched_time_field, :class => "timepicker" %>

答案 1 :(得分:6)

您可以使用date_time_attribute gem

class MyModel < ActiveRecord::Base
  include DateTimeAttribute

  date_time_attribute :scheduled_at
end

它允许您分别设置schedule_at_datescheduled_at_time。设置属性后,值将合并到schedule_at

答案 2 :(得分:5)

如果您有专业订阅See this Railscast,则可以使用虚拟属性the revised one

基本上在视图中你会看到以下内容

<%= f.label :date_field %>
<%= f.text :date_field %>
<%= f.label :time_field %>
<%= f.text :time_field %>

您的数据库仍会保留一个我称之为full_date

的字段

现在,在您的模型中,您必须按如下方式定义上述两个字段。

def date_field  # What this returns will be what is shown in the field
  full_date.strftime("%m-%d'%y") if full_date.present?
end 

def time_field
  full_date.strftime("%I:%M%p") if full_date.present?
end

def time_field=(time)
  full_date = DateTime.parse("#{date_field} #{time_field})
end

由于看起来您使用的是Rails 4,因此您必须在强参数中允许date_field和time_field。

答案 3 :(得分:0)

或者,我在控制器中设置了一个解决方案,该解决方案在创建对象之前执行所有日期时间转换,因为更改模型中的数据会影响我的所有测试和验证。 “事件”是我在此处创建的对象,并为其分配了日期时间值。

#In the controller:
def convert_to_datetime_and_assign(event, params)
  date_field = Date.parse(params[:date_field]).strftime("%Y-%m-%d")
  start_time_field = Time.parse(params[:start_time_field]).strftime("%H:%M:%S")
  end_time_field = Time.parse(params[:end_time_field]).strftime("%H:%M:%S")
  event.start_time = DateTime.parse("#{date_field} #{start_time_field}")
  event.end_time = DateTime.parse("#{date_field} #{end_time_field}")
  event
rescue ArgumentError
  event.errors.add(:start_time, :invalid, message: "Date or time was invalid")
  event
end

在创建和更新控制器方法中,我将上述方法称为:

@event = convert_to_datetime_and_assign(@event, event_params)

我在表单中为date_field,start_time_field和end_time_field添加了字段,用于创建/更新“事件”。在模型中,我添加了一个访问器,以便能够访问这些值。

attr_accessor :date_field, :start_time_field, :end_time_field