«каждая» / «карта» в массиве приводит к «у вас есть нулевой объект, когда вы его не ожидали» в create_time_zone_conversion_attribute ?, время от времени - PullRequest
0 голосов
/ 09 ноября 2010

У меня есть кнопка, которая отправляет запрос на получение через XHR определенному действию на сервере rails. Это действие вызывает функцию, которую я определил в модели «Категория». Эта функция делает что-то вроде x = Category.subcategories, а в следующей строке что-то вроде x.map (&: id) или x.each {| x | y << x.id}. (Категория has_many: подкатегории). В моей среде разработки это работает на 1-10 нажатий на эту кнопку, но затем перестает работать по следующей причине: </p>

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?

Со следующим дампом:

C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:142:in `create_time_zone_conversion_attribute?'
C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:75:in `define_attribute_methods'
C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:71:in `each'
C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:71:in `define_attribute_methods'
C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:355:in `respond_to?'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `method_missing'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `map'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `send'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `method_missing'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:369:in `method_missing'
C:/MyApp/app/models/category.rb:24:in `fetch_prices_grouped_by_date'
C:/MyApp/app/controllers/categories_controller.rb:103:in `show'

Перезапуск сервера устраняет проблему на следующие 1-10 кликов, а затем снова появляется. При отладке этой строки (в среде IDE NetBeans, ruby-debug-ide-0.3.1) я получаю (после пересечения 1-10 "хороших кликов") метод__произведения (method = "map", self = "{Array, 23 элемента} "), и если я попытаюсь расширить наблюдение за переменной x, сервер отладки вылетит. Следуя совету этого поста , я отредактировал свой environment.rb и включил кэширование классов:

config.cache_classes = true

и проблема решена. Тем не менее, очень раздражает перезапуск сервера после каждого изменения в коде, и мне было интересно, есть ли у кого-нибудь представление о том, что происходит, почему изменение cache_classes решает это, и если есть какой-либо другой обходной путь, который не несет боль перезапуска после каждого редактирования.

Я использую Rails 2.3.8.

Большое спасибо, Amit

EDIT:

ОК, поэтому после некоторой дополнительной отладки я понимаю, что по какой-либо причине в create_time_zone_conversion_attribute для skip_time_zone_conversion_for_attributes установлено значение nil? метод (active_record / attribute_methods.rb).

Найдена эта статья после некоторых исследований. Добавление:

self.skip_time_zone_conversion_for_attributes = []

к модели не работает.

Замена в среде. Rb

config.time_zone = 'UTC'

с

config.active_record.default_timezone = :utc

у меня тоже не работает, так как я получаю "слишком большой уровень стека" с:

C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:237:in `method_missing'
C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:253:in `method_missing'
C:/MyApp/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:211:in `to_proc'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:369:in `method_missing'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `map'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `send'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:215:in `method_missing'
C:/MyApp/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:369:in `method_missing'
C:/MyApp/app/models/category.rb:24:in `fetch_prices_grouped_by_date'
C:/MyApp/app/controllers/categories_controller.rb:103:in `show'

Я исследую это далее, чтобы увидеть, является ли это просто конкретной проблемой с моим кодом.

РЕДАКТИРОВАТЬ # 2

Хорошо, в соответствии с рекомендацией этой статьи я отредактировал строку attribute2_methods.rb 252 и изменил ее на:

if self.class.primary_key.to_s == method_name

до:

if false and self.class.primary_key.to_s == method_name

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

Спасибо! Amit

Редактировать # 3

Хорошо, это последнее изменение сломало другие части моего приложения. Я повторил этот вопрос здесь .

1 Ответ

0 голосов
/ 11 ноября 2010

Наконец-то решено! После публикации третьего вопроса и с помощью trptcolin я смог подтвердить работоспособное решение.

Проблема: я использовал require для включения моделей из моделей без таблиц (классы, которые находятся в приложении / моделях, но не расширяют ActiveRecord :: Base). Например, у меня был класс FilterCategory, который выполнял require 'category'. Это перепуталось с кэшированием классов в Rails. Во-первых, мне пришлось использовать require, так как такие строки, как Category.find :all не удалось.

Решение (в кредит входит trptcolin): замените Category.find :all на ::Category.find :all. Это работает без необходимости явно требовать какой-либо модели и, следовательно, не вызывает проблем с кэшированием классов.

Проблема «слишком большой стек» также исчезает при использовании config.active_record.default_timezone = :utc

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