Ruby-on-rails <NoMethodError: #<Record::ActiveRecord_Relation 的未定义方法`read_attribute_for_serialization':

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38510327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:27:10  来源:igfitidea点击:

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

ruby-on-railsactive-model-serializers

提问by curt

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.

这是控制器 RecordsContrller 的替代序列化程序。另一个,'RecordsSerializer,工作正常。

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.

到发生错误的类。它对我不起作用。我还查看了 gem 文档。我找到了一个使用序列化程序的例子:。很明显需要任何其他代码。

I'm using Ruby 2.3.0 and Rails 5.0.0.

我使用的是 Ruby 2.3.0 和 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

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

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.

我刚刚注意到,主键 id 没有出现在架构中。我在 Sequel Pro 中查看表结构时看到它。

Update

更新

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

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

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

回答by Kem

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

我遇到了同样的错误,发现在控制器中更改serializer:each_serializer:解决了这个问题。

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

record_summary_serializer.rb- 可以删除包含行

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

From active_model_serializers documentation.

来自 active_model_serializers文档

Updated link. thanks Lowryder

更新链接。谢谢洛瑞德

回答by JMazzy

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

您需要添加include ActiveModel::Serialization到您的模型中。默认情况下,ActiveModel 中不包含扩展序列化。在 GitHub 上查看此答案

回答by Eliot Sykes

<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:

当被序列化的对象是nil. 考虑打印调试您正在序列化的对象以检查它是否nil

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

If the object (productin the snippet above) is nil, then you may see the NoMethodErrorreported above due to nil.read_attribute_for_serializationbeing called.

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

回答by curt

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:

我通过将自定义序列化程序更改为 RecordDetailSerializer 并从控制器中的 show 方法调用它来解决我的直接问题。当我删除包含 @JMazzy 建议它仍然有效。仍然有一些棘手的事情。如果我在 index 方法中使用自定义方法:

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:

我在上面问题底部显示的缺少 id 上收到错误消息。但是,当我在我的 show 方法中使用它时:

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.

如果我删除问题字段,列表中的下一个字段就会成为问题。这对我来说不再是问题,因为我总是可以将自定义序列化器限制为单个元素。