<NoMethodError: undefined method `read_attribute_for_serialization' for #<Record::ActiveRecord_Relation:

匿名 (未验证) 提交于 2019-12-03 03:04:01

问题:

I'm getting the error:

<NoMethodError: undefined method `read_attribute_for_serialization' for #<Record::ActiveRecord_Relation:0x007faa7cfe3318>> 

The error is on third line of the snippet.

  def artist     @records = Record.where('artist_id = ' + params[:artist_id])     render :json => @records, serializer: RecordSummarySerializer   end 

This is an alternate serializer for the controller RecordsContrller. The other one, 'RecordsSerializer, works fine.

A search on this error brought up a few solutions. Some were unclear as to where one would add code. Another suggested adding:

alias :read_attribute_for_serialization :send 

to the class where the error occurs. It didn't work for me. I also looked through the gem documentation. I found an example of the use of serializer:. It was clear any other code was needed.

I'm using Ruby 2.3.0 and Rails 5.0.0.

Controller

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 

Model

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 

record_summary_serializer.rb

include ActiveModel::Serialization class RecordSummarySerializer < ActiveModel::Serializer   attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,              :recording_date, :penguin, :category end 

record_serializer.rb

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 

Schema for Records

  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 

I just noticed, the primary key, id, doesn't appear in the schema. I see it in Sequel Pro when I view the table structure.

Update

I added the the code suggested by @JMazzy. I now get the error:

<NoMethodError: undefined method `id' for #<Record::ActiveRecord_Relation:0x007faa8005a9d8>\nDid you mean?  ids> 

回答1:

I had the same error and found changing serializer: to each_serializer: in the controller solved the issue.

Controller

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 - can remove the include line

class RecordSummarySerializer < ActiveModel::Serializer   attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,              :recording_date, :penguin, :category end 

From active_model_serializers documentation.

Updated link. thanks Lowryder



回答2:

You need to add include ActiveModel::Serialization to your model. Extended serialization is not included by default in ActiveModel. See this answer on GitHub.



回答3:

<NoMethodError: undefined method `read_attribute_for_serialization' 

This error can happen when the object being serialized is nil. Consider print debugging the object you are serializing to check if it is nil:

def show   product = Product.find_by(id: params[:id])   p "Is product nil? #{product.nil?}"   render json: product end 

If the object (product in the snippet above) is nil, then you may see the NoMethodError reported above due to nil.read_attribute_for_serialization being called.



回答4:

I fixed my immediate problem by changing the custom serializer to RecordDetailSerializer and calling it from my show method in the controller. When I removed the include @JMazzy suggested it still worked. There is still something screwy. If I use the custom method in the index method:

def index   @records = Record.order('title')   render :json => @records, serializer: RecordDetailSerializer end 

I get the error on the missing id shown at the bottom of my question above. However, when I use it in my show method:

def show   @record = Record.find(params[:id])   render :json => @record, serializer: RecordDetailSerializer end 

If I remove the problem field, the next field in the list becomes the problem. This no a longer a problem for me as I can always limited custom serializers to and individual element.



文章来源:
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!