<NoMethodError:#Record :: ActiveRecord_Relation的未定义方法`read_attribute_for_serialization':

cur*_*urt 24 ruby-on-rails active-model-serializers

我收到错误:

<NoMethodError: undefined method `read_attribute_for_serialization' for #<Record::ActiveRecord_Relation:0x007faa7cfe3318>>
Run Code Online (Sandbox Code Playgroud)

该错误位于代码段的第三行.

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

这是控制器RecordsContrller的备用序列化程序.另一个,'RecordsSerializer,工作正常.

对此错误的搜索提出了一些解决方案.有些人不清楚添加代码的位置.另一位建议补充:

alias :read_attribute_for_serialization :send
Run Code Online (Sandbox Code Playgroud)

到发生错误的类.它对我不起作用.我还查看了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
Run Code Online (Sandbox Code Playgroud)

模型

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

记录模式

  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
Run Code Online (Sandbox Code Playgroud)

我刚注意到,主键id不会出现在架构中.当我查看表结构时,我在Sequel Pro中看到它.

更新

我添加了@JMazzy建议的代码.我现在得到错误:

<NoMethodError: undefined method `id' for #<Record::ActiveRecord_Relation:0x007faa8005a9d8>\nDid you mean?  ids>
Run Code Online (Sandbox Code Playgroud)

Kem*_*Kem 42

我有同样的错误,发现改变serializer:each_serializer:控制器解决了问题.

调节器

class RecordsController < ApplicationController
...
  def artist
    @records = Record.where('artist_id = ' + params[:artist_id])
    render :json => @records, each_serializer: RecordSummarySerializer
  end
...
end
Run Code Online (Sandbox Code Playgroud)

record_summary_serializer.rb - 可以删除包含行

class RecordSummarySerializer < ActiveModel::Serializer
  attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,
             :recording_date, :penguin, :category
end
Run Code Online (Sandbox Code Playgroud)

来自active_model_serializers 文档.

更新了链接.谢谢洛瑞德

  • 将`serializer`改为`each_serializer`对我有用.谢谢! (5认同)
  • Doc链接已经死了,这里有一个新链接:https://github.com/ggordon/active_model_serializers/blob/master/README.md#2-for-an-array-resource (3认同)

JMa*_*zzy 18

您需要添加include ActiveModel::Serialization到您的模型中.ActiveModel中默认不包括扩展序列化.在GitHub上看到这个答案.


Eli*_*kes 5

<NoMethodError: undefined method `read_attribute_for_serialization'
Run Code Online (Sandbox Code Playgroud)

当序列化的对象是时,可能会发生此错误nil.考虑打印调试您要序列化的对象以检查它是否nil:

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

如果对象(product在上面的代码段中)是nil,那么NoMethodError由于nil.read_attribute_for_serialization被调用,您可能会看到上面报告的内容.