ActiveModel :: MissingAttributeError возникает после развертывания, а затем исчезает через некоторое время - PullRequest
46 голосов
/ 25 июля 2011

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

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

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

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

Ответы [ 7 ]

122 голосов
/ 27 июля 2011

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

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

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

7 голосов
/ 24 января 2015

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

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

2 голосов
/ 26 декабря 2014

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

2 голосов
/ 30 июня 2014

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

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

2 голосов
/ 03 ноября 2011

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

Для упрощения это было что-то вроде:

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".

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

0 голосов
/ 29 января 2014

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

0 голосов
/ 30 января 2013

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

rescue ActiveRecord::MissingAttributeError 

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

...