エラーが発生しています:
<NoMethodError: undefined method `read_attribute_for_serialization' for #<Record::ActiveRecord_Relation:0x007faa7cfe3318>>
エラーはスニペットの3行目にあります。
def artist
@records = Record.where('artist_id = ' + params[:artist_id])
render :json => @records, serializer: RecordSummarySerializer
end
これは、コントローラーRecordsContrllerの代替シリアライザーです。もう1つ、「RecordsSerializer」は正常に動作します。
このエラーを検索すると、いくつかの解決策が見つかりました。コードを追加する場所が不明な人もいました。別の提案を追加:
alias :read_attribute_for_serialization :send
エラーが発生したクラスに。私にはうまくいきませんでした。また、gemのドキュメントにも目を通しました。シリアライザーの使用例を見つけました。他のコードが必要であることは明らかでした。
私はRuby 2.3.0およびRails 5.0.0。
class RecordsController < ApplicationController
...
def index
@records = Record.order('title')
render :json => @records
end
def artist
@records = Record.where('artist_id = ' + params[:artist_id])
render :json => @records, serializer: RecordSummarySerializer
end
...
end
class Record < ActiveRecord::Base
belongs_to :artist
belongs_to :label
belongs_to :style
has_many :tracks
has_many :credits
validates :title, presence: true
validates :catalog, presence: true
end
include ActiveModel::Serialization
class RecordSummarySerializer < ActiveModel::Serializer
attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,
:recording_date, :penguin, :category
end
class RecordSerializer < ActiveModel::Serializer
attributes :id, :artist_id, :label_id, :style_id, :title, :catalog, :alternate_catalog,
:recording_date, :notes, :penguin, :category
has_one :artist
has_many :tracks
end
create_table "records", unsigned: true, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "title", limit: 50
t.string "catalog", limit: 20, null: false
t.string "alternate_catalog", limit: 20
t.integer "artist_id", unsigned: true
t.integer "label_id", null: false, unsigned: true
t.integer "style_id", unsigned: true
t.datetime "recording_date"
t.text "notes", limit: 4294967295
t.string "penguin", limit: 50
t.string "category", limit: 50, default: "jazz"
t.index ["artist_id"], name: "RecordHasOneArtist", using: :btree
t.index ["label_id"], name: "RecordHasOneLabel", using: :btree
t.index ["style_id"], name: "RecordHasOneStyle", using: :btree
end
主キーidがスキーマに表示されないことに気付きました。テーブル構造を表示すると、Sequel Proに表示されます。
@JMazzyによって提案されたコードを追加しました。私は今エラーを受け取ります:
<NoMethodError: undefined method `id' for #<Record::ActiveRecord_Relation:0x007faa8005a9d8>\nDid you mean? ids>
同じエラーが発生し、serializer:
からeach_serializer:
コントローラーで問題を解決しました。
コントローラー
class RecordsController < ApplicationController
...
def artist
@records = Record.where('artist_id = ' + params[:artist_id])
render :json => @records, each_serializer: RecordSummarySerializer
end
...
end
record_summary_serializer.rb-インクルード行を削除できます
class RecordSummarySerializer < ActiveModel::Serializer
attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,
:recording_date, :penguin, :category
end
Active_model_serializersから ドキュメント 。
リンクを更新しました。おかげでLowryder
モデルにinclude ActiveModel::Serialization
を追加する必要があります。 ActiveModelにはデフォルトで拡張シリアル化は含まれていません。 GitHubのこの回答 を参照してください。
<NoMethodError: undefined method `read_attribute_for_serialization'
このエラーは、シリアル化されるオブジェクトがnil
の場合に発生する可能性があります。 nil
であるかどうかを確認するために、シリアル化するオブジェクトのデバッグを印刷することを検討してください。
def show
product = Product.find_by(id: params[:id])
p "Is product nil? #{product.nil?}"
render json: product
end
オブジェクト(上記のスニペットのproduct
)がnil
である場合、nil.read_attribute_for_serialization
が呼び出されているため、上記のNoMethodError
が表示される場合があります。
カスタムシリアライザーをRecordDetailSerializerに変更し、コントローラーのshowメソッドから呼び出して、当面の問題を修正しました。インクルードを削除したとき、@ JMazzyはまだ機能することを示唆しました。まだ厄介なものがあります。インデックスメソッドでカスタムメソッドを使用する場合:
def index
@records = Record.order('title')
render :json => @records, serializer: RecordDetailSerializer
end
上記の質問の下部に表示されている欠落しているIDでエラーが発生します。ただし、showメソッドで使用する場合:
def show
@record = Record.find(params[:id])
render :json => @record, serializer: RecordDetailSerializer
end
問題のフィールドを削除すると、リストの次のフィールドが問題になります。カスタムシリアライザーを常に個別の要素に制限できるため、これはもはや問題ではありません。