2010-11-22 2 views
1

Я работаю с Ruby on Rails 3.0 в базе данных readonly oracle (через oracle_enhanced_adapter).Rails 3 и Oracle: NLS Настройки отклоняют десятичный разделитель

Запуск в известную проблему «n + 1 запросов» я попробовал метод includes.
В отличие от описания в Rails, созданный второй запрос перечисляет требуемые идентификаторы не как целые числа, а как строковые представления значений float. Исходные идентификаторы имеют тип NUMBER.

К сожалению, базы данных NLS установлены для Германии, включая NLS_NUMERIC_CHARACTERS, который ожидает «,» как десятичный разделитель. Поэтому я всегда получаю ORA-01722 Ошибка as described here.

Более точно:

@var.assoc.includes(:another_assoc).where("column_1 = ?", some_value)

дает

ActiveRecord::StatementInvalid: OCIError: ORA-01722: invalid number: SELECT "TABLE_A".* FROM "TABLE_A" WHERE ("TABLE_A"."ID" IN ('1715.0','1716.0','1717.0','1718.0','1719.0','1720.0','1721.0'))

(я должен был упростить код Rail выше, поскольку в нем содержатся некоторые отвлекающие детали, как "строки в символ" преобразования)

Как уже упоминалось, база данных считывается только с использованием

alter session set nls_numeric_characters = '.,' 

работал непосредственно в базе данных. Но я не смог найти правильный способ изменить сеанс рельсов.

Все, что я нашел, похоже, относится к Rails 2 или использует устаревшие функции.
Как это решить для Rails 3.0?

Альтернативно: Как я могу заставить Rails (или, возможно, oracle_enhanced_adapter) преобразовать все перечисленные идентификаторы в Fixnum?

Спасибо и наилучшими пожеланиями, Тим

+0

Привет Тим, добро пожаловать в stackoverflow. Не могли бы вы опубликовать код rails, генерирующий это утверждение? – Patrick

ответ

1

У нас была та же проблема, с помощью Oracle, и мы решили ее, поместив следующий код в инициализаторе (поместите его в config/initializers/something.rb):

BigDecimal.class_eval do 
    alias :old_to_s :to_s 

    def to_s(format='F') 
    old_result = self.old_to_s(format) 
    (old_result[-2..-1] == ".0" ? old_result[0..-3] : old_result) 
    end 
end 

It вызвано типом столбца, который вы используете в качестве первичного ключа. Если вы объявите его как NUMBER, он будет преобразован в BigDecimal. В качестве альтернативы вы можете объявить свой идентификатор как NUMBER(10) или что-то подобное, которое, очевидно, будет отображаться на FixNum (чей идентификатор будет правильно преобразован).

Надеюсь, это поможет.

+0

спасибо, ребята, вы здорово :-) – bunter

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