Изменения в форме не сохраняются в базе данных - программирование
Подтвердить что ты не робот

Изменения в форме не сохраняются в базе данных

Я пытаюсь добавить поле даты в свою форму.

Я добавил bootstrap-datepicker-rails gem, все необходимые css и javascript.

Когда я выбираю дату в календаре и нажимаю "Сохранить", она не обновляется в базе данных.

Здесь код формы:

= simple_form_for @model
  = f.input :date_last, :required => true, 
            :input_html => { data: {behaviour: "datepicker"}}, 
            :as => :string
  = f.button :submit, 'Save', :class => 'btn btn-primary'

Я думаю, что это может быть связано с форматами, но не уверен, на что смотреть.

Обновить

Он работает, когда я меняю формат по умолчанию на yyyy-mm-dd (по умолчанию - mm/dd/yyyy):

$('[data-behaviour~=datepicker]').datepicker({"format": "yyyy-mm-dd", "weekStart": 1, "autoclose": true});
4b9b3361

Ответ 1

Я просто ответил на аналогичный вопрос здесь и включил свой ответ ниже:


Мне также нужно было выполнить эту работу и поддерживать несколько локалей, которые не используют ориентированные на США форматы даты, например: en-AU (Австралия), которая имеет формат даты dd/mm/yyyy.

Проблема

Rails ожидает, что формат даты будет yyyy-mm-dd в браузере, но вы хотите отобразить дату в локали пользователя. Хотя элемент управления датой позволяет вам указать формат отображения, он НЕ позволяет отдельно указывать формат, который будет отправлен обратно на сервер.

Решение

Создайте скрытое поле ввода, которое отправит правильный формат обратно на ваш сервер rails. Я делаю это с помощью настраиваемого элемента управления ввода simple_form, который строит поле ввода даты и скрытое поле и использует некоторый javascript для преобразования в дату рельсов при изменении управления вводом.

Результат: у вас может быть хороший выборщик бутстрапов в рельсах и использовать его с помощью simple_form следующим образом:

<%= f.input :date, as: :bootstrap_datepicker %>

Или использовать формат длинных дат:

<%= f.input :date, as: :bootstrap_datepicker, input_html: { format: :long } %>

Реализация

Создайте или отредактируйте следующие файлы:

Gemfile

gem 'bootstrap-sass'
gem 'bootstrap-datepicker-rails'

<сильные > Config/локалей/ен-AU.yml

en-AU:
  date:
    datepicker:
      default: "dd/mm/yyyy"
      long: "dd MM, yyyy"
    formats:
      default: ! '%d/%m/%Y'
      long: ! '%d %B, %Y'

<сильные > Config/локалей/ен-US.yml

en-US:
  date:
    datepicker:
      default: "mm/dd/yyyy"
      long: "MM dd, yyyy"
    formats:
      default: "%m/%d/%Y"
      long: ! '%B %d, %Y'

приложение/активы/таблицы стилей /application.css.scss

@import "bootstrap-responsive";
@import "bootstrap-datepicker";

приложение/активы/JavaScripts/application.js.coffee

#= require bootstrap
#= require bootstrap-datepicker
#= require bootstrap-datepicker-rails

В качестве альтернативы app/assets/javascripts/application.js

//= require bootstrap
//= require bootstrap-datepicker
//= require bootstrap-datepicker-rails

приложение/активы/JavaScripts/bootstrap-datepicker-rails.js.coffee

$ ->
  # convert bootstrap-datepicker value to rails date format (yyyy-mm-dd) on our hidden field
  $(document).on 'changeDate', '.bootstrap-datepicker', (evt) ->
    rails_date = evt.date.getFullYear() + '-' + ('0' + (evt.date.getMonth() + 1)).slice(-2) + '-' + ('0' + evt.date.getDate()).slice(-2)
    $(this).next("input[type=hidden]").val(rails_date)

приложение/входы/bootstrap_datepicker_input.rb

class BootstrapDatepickerInput < SimpleForm::Inputs::Base
  def input
    text_field_options = input_html_options.with_indifferent_access
    format =  text_field_options.delete(:format)
    hidden_field_options = text_field_options.dup
    hidden_field_options[:class] = text_field_options[:class].dup # so they won't work with same array object
    hidden_field_options[:id] = "#{attribute_name}_hidden"
    text_field_options[:class] << 'bootstrap-datepicker'
    text_field_options[:type] = 'text'
    text_field_options[:value] ||= format_date(value(object), format)
    set_data_option text_field_options, 'date-format', I18n.t(format, scope: [:date, :datepicker], default: :default)
    default_data_option text_field_options, 'provide', 'datepicker'

    return_string =
      "#{@builder.text_field(attribute_name, text_field_options.to_hash)}\n" +
      "#{@builder.hidden_field(attribute_name, hidden_field_options.to_hash)}\n"
    return return_string.html_safe
  end

protected

  def default_data_option(hash, key, value)
    set_data_option(hash,key,value) unless data_option(hash, key)
  end

  def data_option(hash, key)
    hash[:data].try(:[],key) || hash["data-#{key}"]
  end

  def set_data_option(hash, key, value)
    hash[:data].try(:[]=,key,value) || (hash["data-#{key}"] = value)
  end

  def value(object)
    object.send @attribute_name if object
  end

  def format_date(value, format=nil)
    value.try(:strftime, I18n.t(format, scope: [ :date, :formats ], default: :default))
  end
end

Ответ 2

Я столкнулся с подобной проблемой и форматом преобразования в создании действия решил для меня:

def create
     .....
     @person.dob = DateTime.strptime(params[:person][:dob], '%m/%d/%Y').to_date
     .....
     @person.save
     .....
end

Ответ 3

Ответ Andrew Hacking отлично поработал у меня, с двумя небольшими изменениями в приложении/входах/bootstrap_datepicker_input.rb. Я использую Rails 4.2.0. Он игнорировал значение в скрытом поле как дубликат (поскольку ввод текста и скрытый ввод имеют одинаковые атрибуты "имя" ). Я переключил:

"#{@builder.text_field(attribute_name, text_field_options.to_hash)}\n"

... к этому:

"#{@builder.text_field(attribute_name.to_s+'_box',text_field_options.to_hash)}\n" +

Кроме того, я терял параметры оболочки, поэтому я добавил аргумент input и объединил параметры оболочки в опции html.

Это:

def input
    text_field_options = input_html_options.with_indifferent_access
    ...

... стал:

def input(wrapper_options)
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    text_field_options = merged_input_options.with_indifferent_access
    ...

Ответ 4

Я использовал anwser от Эндрю. Он работал хорошо для меня, за исключением того, что он не отображал правильные имена локализованных месяцев (например, июль вместо Juli).

Вот мой подход, если вы хотите использовать локализованную версию для вашего date_picker.

По умолчанию в bootsrap-datepicker gem загружаются все языковые версии.

Если вы хотите, например, загрузить только английскую и немецкую версии, вы должны изменить application.js

от

//= require bootstrap-datepicker

к

//= require bootstrap-datepicker/core
//= require bootstrap-datepicker/locales/bootstrap-datepicker.en-GB.js
//= require bootstrap-datepicker/locales/bootstrap-datepicker.de.js

Шаг Nest заключается в изменении BootstrapDatepickerInput

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

поэтому добавьте следующую строку к вам. Класс ввода внутри метода ввода

set_data_option text_field_options, 'date-language', input_html_options[:locale]

На наш взгляд, теперь мы можем назвать форму с

= f.input :your_attribute_name, as: :bootstrap_datepicker, input_html: { locale: locale }