2010-09-09 3 views
41

У меня есть модель ActiveRecord Event с колонкой datetime starts_at. Я хотел бы представить форму, в которой дата и время для starts_at выбраны отдельно (например, "23-10-2010" для даты и "18:00" за время). Эти поля должны подкрепляться одним столбцом starts_at, а проверки должны быть предпочтительно равными starts_at.Отдельные поля даты и времени в Rails

Я могу, конечно, обманывать виртуальными атрибутами и крючками, но мне хотелось бы более элегантное решение. Я экспериментировал как с composed_of (rdoc), так и с атрибутом-декоратором (lighthouse discussion, github) без успеха.

Ниже грубый набросок того, что я хотел ..

class Event < ActiveRecord::Base 
    validates_presence_of :start_date 
end 

# View 
# On submission this should set start_date. 
form_for @event do |f| 
    f.text_field :starts_at_date   # date-part of start_date 
    f.text_field :starts_at_time_of_day # time-of-day-part of start_date 
    f.submit 
end 

Любая помощь приветствуется.

+0

Я столкнулся с этим несколько раз сейчас, но до сих пор не нашел приятного решения. Причина его расщепления заключается в том, что я могу использовать datepicker и time_select отдельно. – benvds

ответ

9

смотрел на это сегодня для проекта Rails, и наткнулся на этот драгоценный камень:

https://github.com/shekibobo/time_splitter

Установка DateTimes может быть трудным или уродливая вещь, особенно через веб-форму. Найти хорошего DatePicker или TimePicker легко, но заставить их работать на обоих может быть сложно. TimeSplitter автоматически генерирует аксессуар для даты, времени, часа и минут в ваших атрибутах времени и времени, что делает тривиальным использование разных входных форм для установки разных частей поля datetime.

Похоже, он будет делать работу за вас

+0

Есть ли способ установить часовой пояс для этого драгоценного камня? Он всегда сохраняется в UTC. –

+0

В моем тестировании он использовал настроенный часовой пояс. Вы уверены, что правильно настроили его? – asgeo1

+0

Я попытался использовать этот камень и сразу столкнулся с проблемой http://stackoverflow.com/questions/29858627/time-splitter-gem-getting-uninitialized-constant-sheettimesplitter –

0

Это из-за проблемы с дизайном? Это действительно намного проще, если вы просто сохранить starts_at как тип данных даты и времени и использовать что-то вроде:

http://puna.net.nz/timepicker.htm#

Он просто работает на вершине все поля даты у вас есть для вашей модели.

+1

Нет, это не проблема дизайна. Данные должны быть одним столбцом, в то время как построитель форм должен обрабатывать 2 разных атрибута для этого же столбца. – benvds

38

Нужно ли иметь вид text_field?

Насколько я могу судить, вы можете иметь поле date_time, а затем просто использовать два разных поля ввода для установки разных частей поля.

form_for @event do |f| 
    f.date_select :starts_at 
    f.time_select :starts_at, :ignore_date => true 
    f.submit 
end 

С указанием даты и времени рельсы выберите хелперы набор пять различных параметров (starts_at(1i) за год часть, 2i за месяц части, и так далее), что означает, что date_select устанавливает их только в части даты, в то время как если вы пройдете до time_select, он установит только час и минуту.

Если у вас должен быть text_field, я не уверен, как это сделать, но, возможно, с помощью какой-либо магии jQuery возможно установить параметры даты и времени перед отправкой формы.

+1

Ницца, кажется, работает и достаточно хорошо для решения. Но то, что я действительно хотел бы увидеть, - это способ разделить и восстановить атрибуты вокруг помощника формы. Например. before_form_build & before_form_validation. – benvds

+0

Тогда я думаю, вам нужно будет вручную рубить хакс на params hash. – Frost

2

элегантное решение может обеспечить date_time_attribute gem:

class MyModel < ActiveRecord::Base 
    include DateTimeAttribute 

    date_time_attribute :starts_at 
end 

Это позволит вам установить starts_at_date и starts_at_time отдельно:

form_for @event do |f| 
    f.text_field :starts_at_date 
    f.text_field :starts_at_time 
    f.submit 
end 

# this will work too: 
form_for @event do |f| 
    f.date_select :starts_at_date 
    f.time_select :starts_at_time, :ignore_date => true 
    f.text_field :starts_at_time_zone 
    f.submit 
end 

# or 
form_for @event do |f| 
    f.date_select :starts_at_date 
    f.text_field :starts_at_time 
    f.submit 
end 

Он также позволит вам играть с часовыми поясами, использовать хронику и т. Д.

+0

Вы уверены, что можете смешивать 'date_select' и 'text_field'? Я не смог использовать 'text_field' и' time_select', и нет никакой документации, показывающей, что вы можете. –

+0

Вам не нужно включать модуль DateTimeAttribute, как сказано в README репозитория драгоценного камня: https://github.com/einzige/date_time_attribute#rails-users –

3

Использование date_select и time_select - хороший способ пойти.

Тем не менее, я хотел получить text_field на дату (так что я могу использовать дату выборщика JavaScript).

Использование strong_parameters или Rails 4+:

модели/event.rb

# Add a virtual attribute 
attr_accessor :start_at_date 

просмотров/События/_form.html.haml

- # A text field for the date, and time_select for time 
= f.label :start_at 
= f.text_field :start_at_date, value: (f.object.start_at.present? ? f.object.start_at.to_date : nil) 
= f.time_select :start_at, :ignore_date => true 

контроллеры/events_controller.rb

# If using a date_select, time_select, datetime_select 
# Rails expects multiparameter attributes 
# Convert the date to the muiltiparameter parts 
def event_params 
    if !!params[:event] && (params[:event]["start_at(4i)"].present? || params[:event]["start_at(5i)"].present?) 

    if params[:event][:start_at_date].present? 
     start_at_date = params[:event][:start_at_date] 
    else 
     start_at_date = Date.today 
    end 
    year = start_at_date.match(/^(\d{4})[\-\/]/)[1] 
    month = start_at_date.match(/[\-\/](\d{2})[\-\/]/)[1] 
    day = start_at_date.match(/[\-\/](\d{2})$/)[1] 
    params[:event]["start_at(1i)"] = year 
    params[:event]["start_at(2i)"] = month 
    params[:event]["start_at(3i)"] = day 
    end 
    ... 
+0

Почему вы используете '!!' в *** если *** сравнение? Что это значит? –

+0

Преобразует значение в логическое (http://stackoverflow.com/questions/524658/what-does-mean-in-ruby), возможно, не требуется. –

+0

Да, это то, что я, но в любом случае благодарю вас за ответ. :) –

Смежные вопросы