如何将 mysql 日期时间字段转换为两个表单字段(1)仅日期,(2)仅时间,并在表单提交时将两个字段组合回日期时间格式?
这将允许使用以下 gem,但将日期存储在单个日期时间字段中:
gem 'bootstrap-datepicker-rails'
gem 'bootstrap-timepicker-rails'
提前致谢!
如何将 mysql 日期时间字段转换为两个表单字段(1)仅日期,(2)仅时间,并在表单提交时将两个字段组合回日期时间格式?
这将允许使用以下 gem,但将日期存储在单个日期时间字段中:
gem 'bootstrap-datepicker-rails'
gem 'bootstrap-timepicker-rails'
提前致谢!
在@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" %>
您可以使用date_time_attribute gem:
class MyModel < ActiveRecord::Base
include DateTimeAttribute
date_time_attribute :scheduled_at
end
它将允许您单独设置schedule_at_date
和设置scheduled_at_time
。设置属性后,值将组合成schedule_at
.
您可以使用虚拟属性请参阅此 Railscast,如果您有专业订阅,请参阅修改后的。
基本上在视图中,您将执行以下操作
<%= f.label :date_field %>
<%= f.text :date_field %>
<%= f.label :time_field %>
<%= f.text :time_field %>
您的数据库仍将保留一个我将调用的字段full_date
现在在您的模型中,您必须按如下方式定义上述 2 个字段。
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 。
或者,我在控制器中设置了一个解决方案,该解决方案在创建对象之前执行所有日期时间转换,因为更改模型中的数据会影响我的所有测试和验证。“事件”是我在这里创建的对象,并为其分配了日期时间值。
#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