web-dev-qa-db-ja.com

ActiveModel :: MissingAttributeErrorはデプロイ後に発生し、しばらくすると消えます

Rails 3.0.9アプリがあります。これをデプロイすると、ActiveModel :: MissingAttributeErrorsが大量に発生し、500が発生します。エラーはかなりランダムに発生し、ページがロードされることがあります、そうでない場合もありますが、属性はすべてデータベース内の既存の属性であり、見つける必要があります。

奇妙な部分は、しばらくするとエラーがなくなることです。突然、問題の発生が停止します。

私はこれに対する解決策を探しましたが、このエラーは主に誰かがModel.all(:select => 'column_x,column_y')を実行し、column_zまたはcache_moneyを使用している場合。私はこれらのことをしていません。

誰でも助けることができますか?

47
philnash

おそらく、すべての列を返さないクエリ(つまり、_:select_を使用)があり、次にcache_moneyがあります。または他のActiveRecordプラグインは_after_initialize_コールバックを使用します。これは、新しいActiveRecordオブジェクトが作成されるたびに(つまり、データベースから取得されると)実行されます。

その初期化コールバックで、何かが_:select_に含まれていない属性にアクセスまたは使用しようとします。この属性に対してnilが返されると予想されますが、代わりにActiveRecord :: MissingAttributeErrorがスローされます。

記事が示唆するようにActiveRecord :: MissingAttributeErrorをレスキューするか、属性にアクセスまたは変更を試みる前にhas_attribute?(:attribute_name)を使用するようにプラグインにパッチを適用できます。

123
randomguy

データベースを更新した後、デプロイまたはサーバーの再起動を行わずに直接この問題が発生している場合、私にとってはうまくいったことがあります:

実行heroku restartそして修正する必要があります。 dynoが再起動する前に古いデータがサーバーにキャッシュされたままになることがあるため、再起動するとすべてのデータがスクラブされ、その種のエラーが発生しなくなります。お役に立てれば。

7
rmtsukuru

コントローラーレンダリングの最後に.to_jsonを追加して、これを修正しました。

2

私はこれについて興味深い見方をしており、同じエラーを引き起こしました。コードを再利用するために、プレゼンタークラスを、グラフビューで使用するグループ化を実行したプレゼンタークラスでサブクラス化します。

簡単にするために、次のようなものでした。

class PostPresenter 
  def query
    Post.where(...stuff....).includes(:wombat)
  end
end

アグリゲーターは次のようなことをして、1日あたりの投稿のテーブルを作成しました。

class AggregatePostPresenter < PostPresenter
  def group_query
    query.select('count(*) as cnt, date(created_at)').group('date(created_at)')
  end
end

「group_query」を呼び出すと、ActiveModel :: MissingAttributeErrorが発生します。「select」に含まれる属性に「wombat_id」が含まれていなかったため、Wombatを「includes」しようとすると失敗するからです。

ただし、キャッシュが有効かどうかに関係なく発生するため、これはおそらくあなたの答えではありません。

2
GSP

この問題が発生しました。 select:には、ビューで参照されるすべてのフィールドが含まれます。含むメソッド内で呼び出される関係IDと属性。

欠落している属性は、ビューとリレーションシップが複雑な場合に特定するのが難しい場合があります。これをデバッグする最も簡単な方法は、select句のwhere部分を削除し、クエリ/スコープ/メソッドが正しく実行されるかどうかを確認することです。その場合、すべての属性をselectに追加し、問題のある属性が見つかるまで、不要な属性を一度に1つずつ削除します。

2
scarver2

同様の問題は、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
blythburgh