Использование нескольких полей ввода для одного атрибута

Я новичок в рельсах, поэтому извините, если это слишком просто.

У меня есть атрибут datetime в моей модели, и я пытаюсь поместить в него значения с 3 элементами формы. Первый - для даты и является формой ввода (я использую bootstrap-datepicker-rails, и я хотел бы придерживаться его). Во втором я хотел бы иметь выборку для часов, а третья - для минут.

Итак, я видел, что могу использовать DateHelpers datetime_select, но тогда я больше не могу использовать bootstrap-datepicker. Итак, какой правильный способ заполнить атрибут (datetime), используя более одного элемента ввода формы. Я видел, что там что-то вроде assign_multiparameter_attributes, но документ не совсем помогает: - (

Спасибо

Ответ 1

Для меня это похоже на проблему для решения контроллера. Модель все еще действительна и будет работать нормально, если она получит свои атрибуты в режиме "Rails". Мое решение включает в себя контроллер, изменяющий хэш params, чтобы модель даже не знала об изменениях в представлении. Это зависит от поведения в ActiveRecord, который можно считать частным API, поэтому... справедливое предупреждение: -)

Скажем, у вас есть эта модель:

# app/models/example.rb
class Example < ActiveRecord::Base
  attr_accessible :started_at    # this is a DateTime
end

Отрегулируйте представление для использования обычного text_field_tag для части даты (которая будет увеличена с помощью bootstrap-datepicker) и Rails time_select для временной части:

# app/views/examples/_form.html.erb
<%= form_for(@example) do |f| %>
  <p>
    <%= f.label :started_at %>
    <%= text_field_tag :started_at, @example.started_at.try(:to_date) %>
    <%= f.time_select :started_at, :ignore_date => true %>
  </p>

  <p><%= f.submit %></p>
<% end %>

Обратите внимание, что мы используем try, поскольку эта форма будет отображаться для новых и сохраненных записей. Это позволяет избежать проблем, когда атрибут started_at nil.

Затем создайте в контроллере before_filter, чтобы изменить хэш params, прежде чем он будет отправлен в модель:

class ExamplesController < ApplicationController
  before_filter :fix_params, :only => [:create, :update]

  # ...

private

  def fix_params
    date = Date.parse(params.delete(:started_at))

    params[:example].merge!({
      'started_at(1i)' => date.year.to_s,
      'started_at(2i)' => date.month.to_s,
      'started_at(3i)' => date.day.to_s
    })
  end
end

По существу, мы анализируем params[:started_at] как дату и присваиваем ему правильные ключи params[:example]. Затем, когда параметры в конечном итоге передаются модели, ActiveRecord правильно присвоит атрибут started_at.

Вам нужно выполнить некоторую проверку и проверку ошибок, но это должно сработать для вас.