ActiveModel:: MissingAttributeError возникает после развертывания, а затем уходит через некоторое время
У меня есть приложение Rails 3.0.9, которое, после его развертывания, страдает от кучи ActiveModel:: MissingAttributeErrors, которые возникают из-за 500s. Ошибки происходят довольно случайным образом, иногда загружается страница, в других случаях она не будет, но атрибуты - это все существующие атрибуты в базе данных и должны быть найдены.
Странная часть заключается в том, что через некоторое время ошибки исчезают. Внезапно они перестают вызывать проблемы.
Я искал решение для этого, но эта ошибка возникает, когда кто-то сделал Model.all(:select => 'column_x,column_y')
и вызывается для column_z
или когда они используют cache_money. Я ничего не делаю.
Может ли кто-нибудь помочь?
Ответы
Ответ 1
Вероятно, у вас есть запрос, который не возвращает все столбцы (т.е. использует :select
), а затем cache_money; или какой-либо другой плагин ActiveRecord использует обратный вызов after_initialize
, который выполняется всякий раз, когда создается новый объект ActiveRecord (т.е. после извлечения из базы данных).
В том, что инициализирует обратный вызов, что-то пытается получить доступ или использовать атрибут, который не был включен в :select
. Вы ожидаете, что это вернет нуль для этого атрибута, но вместо этого вместо него будет создан ActiveRecord:: MissingAttributeError.
Вы можете спасти ActiveRecord:: MissingAttributeError, как предлагает статья, или исправить плагин (ы), чтобы использовать has_attribute?(:attribute_name)
, прежде чем они попытаются получить доступ или изменить атрибут.
Ответ 2
Если у вас возникла эта проблема только после обновления базы данных без каких-либо развертываний или перезапуска сервера, то то, что сработало для меня, может работать для вас:
Запустите heroku restart
, и он должен быть исправлен. Перед тем, как динар перезапускает старые данные, иногда остается кешированным на сервере, поэтому его запуск снова очистит все эти данные и не позволит им вызывать ошибки такого типа. Надеюсь, это поможет.
Ответ 3
Я нашел интересный пример, который привел к той же ошибке. В попытке повторного использования кода мы подклассы класса презентаторов с классом презентаторов, которые выполняли группировку для использования в виде графика.
Чтобы упростить, это было что-то вроде:
class PostPresenter
def query
Post.where(...stuff....).includes(:wombat)
end
end
Чтобы создать таблицу сообщений в день, агрегатор сделал что-то вроде следующего:
class AggregatePostPresenter < PostPresenter
def group_query
query.select('count(*) as cnt, date(created_at)').group('date(created_at)')
end
end
Вызов "group_query" приводит к ActiveModel:: MissingAttributeError, поскольку, я думаю, попытка "включить" Wombat не удалась, потому что "wombat_id" не был в атрибутах, включенных в "select".
Это, вероятно, не ваш ответ, так как это происходит независимо от того, включен ли кеш.
Ответ 4
Я столкнулся с этой проблемой. Убедитесь, что ваш select:
содержит все поля, указанные в вашем представлении, включая любые идентификаторы отношений и любые атрибуты, которые вы вызываете в ваших методах.
Недопустимый атрибут может быть трудно идентифицировать, когда ваши взгляды и отношения сложны. Самый простой способ отладить это - удалить часть select
вашего предложения where
и посмотреть, правильно ли выполняется запрос/область/метод. Если это так, добавьте все атрибуты в select
и удалите ненужные атрибуты один раз в то время, пока не найдете атрибут оскорбления.
Ответ 5
Подобная проблема меня раздражала, когда я пытался сделать запросы Ajax (на самом деле angularjs) для заполнения полей выбора редактирования на месте.
Мне просто нужны атрибуты id и name to_json и продолжали получать MissingAttributeError.
Реализовано, что я получил сам, используя метод as_json в модели, который используется для основного индекса и показывает вызовы модели. В основном это был as_json, который не видел ожидаемых атрибутов.
@foo=Foo.select("id,name")
respond_to do |format|
format.json { render :json => @foo.to_json }
end
дал ошибку, но
respond_to do |format|
format.json { render :json => { :foo=>@foo.as_json(:only=>[:id,:name]) } }
end
похоже, работает. Я был близок к тому, чтобы судить его сам, но я нашел отличное объяснение.
http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/
Ответ 6
Я исправил это, добавив .to_json
в конец моего рендеринга контроллера.
Ответ 7
вам нужно добавить строку
rescue ActiveRecord::MissingAttributeError
в вашем методе after_initialize() модели