Rails 3.0.9アプリがあります。これをデプロイすると、ActiveModel :: MissingAttributeErrorsが大量に発生し、500が発生します。エラーはかなりランダムに発生し、ページがロードされることがあります、そうでない場合もありますが、属性はすべてデータベース内の既存の属性であり、見つける必要があります。
奇妙な部分は、しばらくするとエラーがなくなることです。突然、問題の発生が停止します。
私はこれに対する解決策を探しましたが、このエラーは主に誰かがModel.all(:select => 'column_x,column_y')
を実行し、column_z
またはcache_moneyを使用している場合。私はこれらのことをしていません。
誰でも助けることができますか?
おそらく、すべての列を返さないクエリ(つまり、_:select
_を使用)があり、次にcache_moneyがあります。または他のActiveRecordプラグインは_after_initialize
_コールバックを使用します。これは、新しいActiveRecordオブジェクトが作成されるたびに(つまり、データベースから取得されると)実行されます。
その初期化コールバックで、何かが_:select
_に含まれていない属性にアクセスまたは使用しようとします。この属性に対してnilが返されると予想されますが、代わりにActiveRecord :: MissingAttributeErrorがスローされます。
記事が示唆するようにActiveRecord :: MissingAttributeErrorをレスキューするか、属性にアクセスまたは変更を試みる前にhas_attribute?(:attribute_name)
を使用するようにプラグインにパッチを適用できます。
データベースを更新した後、デプロイまたはサーバーの再起動を行わずに直接この問題が発生している場合、私にとってはうまくいったことがあります:
実行heroku restart
そして修正する必要があります。 dynoが再起動する前に古いデータがサーバーにキャッシュされたままになることがあるため、再起動するとすべてのデータがスクラブされ、その種のエラーが発生しなくなります。お役に立てれば。
コントローラーレンダリングの最後に.to_json
を追加して、これを修正しました。
私はこれについて興味深い見方をしており、同じエラーを引き起こしました。コードを再利用するために、プレゼンタークラスを、グラフビューで使用するグループ化を実行したプレゼンタークラスでサブクラス化します。
簡単にするために、次のようなものでした。
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」しようとすると失敗するからです。
ただし、キャッシュが有効かどうかに関係なく発生するため、これはおそらくあなたの答えではありません。
この問題が発生しました。 select:
には、ビューで参照されるすべてのフィールドが含まれます。含むメソッド内で呼び出される関係IDと属性。
欠落している属性は、ビューとリレーションシップが複雑な場合に特定するのが難しい場合があります。これをデバッグする最も簡単な方法は、select
句のwhere
部分を削除し、クエリ/スコープ/メソッドが正しく実行されるかどうかを確認することです。その場合、すべての属性をselect
に追加し、問題のある属性が見つかるまで、不要な属性を一度に1つずつ削除します。
同様の問題は、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
動作しているようです。私は自分でそれを疑っていましたが、すばらしい説明を見つけました。