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.