Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 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() модели