Rails 4 - Преобразование даты и времени в отдельные поля даты и времени
Как вы можете преобразовать поле datetime mysql в два поля формы (1) только для даты, (2) только время и объединить оба поля обратно в формат даты и времени на форме submit?
Это позволит использовать следующие драгоценные камни, но сохранить даты в одном поле datetime:
gem 'bootstrap-datepicker-rails'
gem 'bootstrap-timepicker-rails'
Спасибо заранее!
Ответы
Ответ 1
Нашел решение с помощью @Althaf
Добавлены виртуальные атрибуты в model.rb. Используется before_save
вызов before_save
для преобразования обратно в datetime.
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" %>
Ответ 2
Вы можете использовать date_time_attribute gem:
class MyModel < ActiveRecord::Base
include DateTimeAttribute
date_time_attribute :scheduled_at
end
Это позволит вам установить schedule_at_date
и scheduled_at_time
отдельно. После того как атрибуты будут установлены, значения будут объединены в schedule_at
.
Ответ 3
Вы можете использовать виртуальные атрибуты. См. Этот 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 в ваших сильных параметрах.
Ответ 4
В качестве альтернативы я установил в контроллере решение, которое выполняет все преобразования даты и времени до создания объекта, поскольку изменение данных в модели оказало влияние на все мои тесты и проверки. "Событие" - это объект, который я создаю здесь, и ему назначены значения даты и времени.
#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