ActiveModel::MissingAttributeError возникает после развертывания, а затем исчезает через некоторое время

У меня есть приложение Rails 3.0.9, которое после развертывания страдает от множества ActiveModel::MissingAttributeErrors, которые возникают, вызывая 500s. Ошибки возникают довольно случайным образом, иногда страница загружается, иногда нет, но все атрибуты существуют в базе данных и должны быть найдены.

Странно то, что через некоторое время ошибки исчезают. Внезапно они перестают вызывать проблемы.

Я искал решение этой проблемы, но эта ошибка в основном возникает либо тогда, когда кто-то сделал Model.all(:select => 'column_x,column_y') и вызывает column_z, либо когда они используют cache_money. Я не делаю ни того, ни другого.

Кто-нибудь может помочь?


person philnash    schedule 25.07.2011    source источник


Ответы (7)


Вероятно, у вас есть запрос, который не возвращает все столбцы (т. е. использует :select), а затем cache_money; или какой-либо другой подключаемый модуль ActiveRecord использует обратный вызов after_initialize, который выполняется всякий раз, когда создается новый объект ActiveRecord (т.е. когда он извлекается из базы данных).

В этом обратном вызове инициализации что-то пытается получить доступ или использовать атрибут, который не был включен в :select. Вы ожидаете, что это вернет nil для этого атрибута, но вместо этого выдается ActiveRecord::MissingAttributeError.

Вы можете спасти ActiveRecord::MissingAttributeError, как предлагается в статье, или исправить плагин(ы), чтобы они использовали has_attribute?(:attribute_name), прежде чем они попытаются получить доступ или изменить атрибут.

person randomguy    schedule 27.07.2011
comment
Спасибо, но, похоже, это не так. У меня нет кэширования или запросов, которые не возвращают все столбцы. - person philnash; 27.07.2011
comment
О, извините, я пропустил ваш оригинальный вопрос. Пожалуйста, опишите ошибки, которые вы получаете, более точно, т.е. предоставьте вывод файла журнала. Он должен сообщать, какой атрибут/столбец в какой модели выдает ActiveModel::MissingAttributeError. - person randomguy; 27.07.2011
comment
+1 Возможно, это не решило вопрос ОП, но это именно та проблема, с которой я столкнулся. - person Nathan; 08.11.2012
comment
Использование has_attribute? сработало для меня в Rails 4, но я до сих пор не уверен, почему. У меня такая же проблема в тесте, и я получаю эту ошибку при использовании try. Вызов has_attribute? до того, как я вызову этот метод получения атрибута, устраняет проблему. - person Ravenstine; 23.03.2016
comment
Не забывайте об областях и областях по умолчанию. - person vzamanillo; 24.01.2019

Если у вас возникла эта проблема только непосредственно после обновления вашей базы данных без каких-либо последующих развертываний или перезапусков сервера, то то, что сработало для меня, может сработать для вас:

Запустите heroku restart, и это должно быть исправлено. Перед перезапуском dyno старые данные иногда остаются в кэше на сервере, поэтому повторный запуск очистит все эти данные и предотвратит появление ошибок такого рода. Надеюсь это поможет.

person rmtsukuru    schedule 24.01.2015

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

Для упрощения это было примерно так:

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» не было в атрибутах, включенных в «выбрать».

Однако это, вероятно, не ваш ответ, поскольку это происходит независимо от того, включен ли кеш.

person GSP    schedule 03.11.2011

Я столкнулся с этой проблемой. Убедитесь, что ваш select: включает все поля, на которые есть ссылки в вашем представлении, включая любые идентификаторы отношений и любые атрибуты, вызываемые в ваших методах.

Отсутствующий атрибут может быть трудно определить, когда ваши представления и отношения сложны. Самый простой способ отладить это — удалить часть select вашего предложения where и посмотреть, правильно ли работает запрос/область/метод. Если это так, добавьте все атрибуты в select и удаляйте ненужные атрибуты по одному, пока не найдете оскорбительный атрибут.

person scarver2    schedule 30.06.2014

Я исправил это, добавив .to_json в конец рендеринга моего контроллера.

person Robbie Guilfoyle    schedule 26.12.2014
comment
Я заинтригован. Как это решило проблему? - person Johnsyweb; 27.11.2015

Подобная проблема раздражала меня, когда я пытался сделать вызовы 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/

person blythburgh    schedule 29.01.2014

вам нужно добавить строку

rescue ActiveRecord::MissingAttributeError 

в вашем методе after_initialize() модели

person Mukul Goyal    schedule 30.01.2013
comment
Лучше использовать has_attribute?(:attr_name) в методе, запускаемом after_initialize, а не на самом деле сталкиваться с ошибкой в ​​первую очередь. - person nonrectangular; 30.04.2015