Формат, используемый при преобразовании и сохранении строки даты в базе данных с рельсами - PullRequest
3 голосов
/ 03 февраля 2011

Мой пользователь хочет использовать формат даты% d /% m /% Y (например, 26.02.2011).

Чтобы правильно отображать даты, я изменил на: формат по умолчанию в environment.rb:

environment.rb :

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(
     :default => "%d/%m/%Y"
)

Работает нормально, но у меня есть одна проблема при попытке сохранить в базе данных строки даты, введенные в этом формате.

Похоже, что Rails принимает строки в формате% m /% d /% Y вместо% d /% m /% Y
02.04.2011 сохраняется как 2011-04-02, а 26.02.2011 просто недействителен и не сохраняется ...

Я искал решения для этого, но те, которые я нашел, полагаются на переформатирование дат в моих моделях, например, приведенное ниже:

mymodel.rb :   

def datefield_formatted
   datefield.strftime '%m/%d/%Y'
end

def datefield_formatted=(value)
   self.datefield = Time.parse(value)
end


view.html.erb :

<%= form.input :datefield_formatted %>

Я мог бы использовать это решение, но оно потребует изменения моих моделей для каждого «поля даты» (в моих приложениях их много).

Поэтому мне было интересно, можно ли было сказать Rails правильно «читать» строку как% d /% m /% Y при конвертации и сохранении в базу данных.

Ответы [ 2 ]

1 голос
/ 03 февраля 2011

В конце концов я нашел решение, более глубоко ищущее Stackoverlow:

Это сообщение в блоге объясняет проблему и дает рабочее решение: http://blog.nominet.org.uk/tech/2007/06/14/date-and-time-formating-issues-in-ruby-on-rails/

Итак, у нас есть: lib / column-patch.rb

class ActiveRecord::ConnectionAdapters::Column

def self.string_to_date(string)
    return string unless string.is_a?(String)

    begin
        return DateTime.strptime(string, ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default])
    rescue
        date_array = ParseDate.parsedate(string)
        # treat 0000-00-00 as nil
        Date.new(date_array[0], date_array[1], date_array[2]) rescue nil
    end
end

def self.string_to_time(string)
    return string unless string.is_a?(String)

    begin
    if dt=Date._strptime(string,ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[:default])
        return Time.mktime(*dt.values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday))
    else
        raise "Bad format"
    end
    rescue
        time_hash = Date._parse(string)
        time_hash[:sec_fraction] = microseconds(time_hash)
        time_array = time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)
        # treat 0000-00-00 00:00:00 as nil
        Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue DateTime.new(*time_array[0..5]) rescue nil
    end
end

end

И мы добавляем config / environment.rb

require 'column-patch'
1 голос
/ 03 февраля 2011

Я думаю, что лучше всего сохранить даты в обычном формате sql (т.е. поля даты, а не varchar) и отображать их только в% d /% m /% Y Для этого я обычно использую файлы локализации и функцию l (дата). например это в файле локализации

date:
  formats:
    default: "%d/%m/%Y"

и это везде, где вы используете дату в представлениях l(date)

Другая идея состоит в том, чтобы перегружать activerecord тем, как он сохраняет даты, но это немного излишне: /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...