serializers rails new custom as_json active ruby-on-rails active-model-serializers

ruby on rails - rails - <NoMethodError: método no definido `read_attribute_for_serialization ''para#<Record:: ActiveRecord_Relation:



rails serializer nested (4)

Estoy recibiendo el error:

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

El error está en la tercera línea del fragmento.

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

Este es un serializador alternativo para el controlador RecordsContrller. El otro, ''RecordsSerializer, funciona bien.

Una búsqueda en este error trajo algunas soluciones. Algunos no tenían claro dónde se agregaría el código. Otro sugirió agregar:

alias :read_attribute_for_serialization :send

a la clase donde se produce el error. No funcionó para mí. También miré a través de la documentación de la gema. Encontré un ejemplo del uso del serializador :. Estaba claro que cualquier otro código era necesario.

Estoy usando Ruby 2.3.0 y Rails 5.0.0.

Controlador

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

Modelo

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

Esquema para Registros

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

Acabo de notar que la clave principal, id, no aparece en el esquema. Lo veo en Sequel Pro cuando veo la estructura de la tabla.

Actualizar

Agregué el código sugerido por @JMazzy. Ahora me sale el error:

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


Solucioné mi problema inmediato cambiando el serializador personalizado a RecordDetailSerializer y llamándolo desde mi método show en el controlador. Cuando quité la inclusión, @JMazzy sugirió que aún funcionaba. Todavía hay algo chiflado. Si utilizo el método personalizado en el método de índice:

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

Recibo el error en la identificación faltante que se muestra al final de mi pregunta anterior. Sin embargo, cuando lo uso en mi método de show:

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

Si elimino el campo problema, el siguiente campo en la lista se convierte en el problema. Esto ya no es un problema para mí, ya que siempre puedo limitar los serializadores personalizados a un elemento individual.


Tuve el mismo error y encontré el cambio de serializer: a each_serializer: en el controlador resolví el problema.

Controlador

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 - puede eliminar la línea de inclusión

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

De la documentation active_model_serializers.

Enlace actualizado. gracias Lowryder


include ActiveModel::Serialization agregar include ActiveModel::Serialization a su modelo. La serialización extendida no se incluye de forma predeterminada en ActiveModel. Ver esta respuesta en GitHub .


<NoMethodError: undefined method `read_attribute_for_serialization''

Este error puede ocurrir cuando el objeto que se serializa es nil . Considere la posibilidad de imprimir la depuración del objeto que está serializando para verificar si es nil :

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

Si el objeto ( product en el fragmento de código anterior) es nil , es posible que vea el NoMethodError informado anteriormente debido a que nil.read_attribute_for_serialization se llama.