Je reçois l'erreur:
<NoMethodError: undefined method `read_attribute_for_serialization' for #<Record::ActiveRecord_Relation:0x007faa7cfe3318>>
L'erreur se trouve sur la troisième ligne de l'extrait.
def artist
@records = Record.where('artist_id = ' + params[:artist_id])
render :json => @records, serializer: RecordSummarySerializer
end
Il s'agit d'un sérialiseur alternatif pour le contrôleur RecordsContrller. L'autre, 'RecordsSerializer, fonctionne très bien.
Une recherche sur cette erreur a permis de dégager quelques solutions. Certains ne savaient pas exactement où ajouter du code. Un autre a suggéré d'ajouter:
alias :read_attribute_for_serialization :send
à la classe où l'erreur se produit. Ça n'a pas marché pour moi. J'ai également regardé la documentation de la gemme. J'ai trouvé un exemple d'utilisation du sérialiseur :. Il était clair que tout autre code était nécessaire.
J'utilise Ruby 2.3.0 et 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
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
include ActiveModel::Serialization
class RecordSummarySerializer < ActiveModel::Serializer
attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,
:recording_date, :penguin, :category
end
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
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
Je viens de remarquer que la clé primaire, id, n'apparaît pas dans le schéma. Je le vois dans Sequel Pro lorsque je regarde la structure de la table.
J'ai ajouté le code suggéré par @JMazzy. Je reçois maintenant l'erreur:
<NoMethodError: undefined method `id' for #<Record::ActiveRecord_Relation:0x007faa8005a9d8>\nDid you mean? ids>
J'ai eu la même erreur et j'ai trouvé la modification serializer:
à each_serializer:
dans le contrôleur a résolu le problème.
Contrôleur
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 - peut supprimer la ligne d'inclusion
class RecordSummarySerializer < ActiveModel::Serializer
attributes :id, :artist_id, :label_id, :style_id, :title, :catalog,
:recording_date, :penguin, :category
end
De active_model_serializers documentation .
Lien mis à jour. merci Lowryder
Vous devez ajouter include ActiveModel::Serialization
à votre modèle. La sérialisation étendue n'est pas incluse par défaut dans ActiveModel. Voir cette réponse sur GitHub .
<NoMethodError: undefined method `read_attribute_for_serialization'
Cette erreur peut se produire lorsque l'objet sérialisé est nil
. Envisagez d'imprimer le débogage de l'objet que vous sérialisez pour vérifier s'il s'agit de nil
:
def show
product = Product.find_by(id: params[:id])
p "Is product nil? #{product.nil?}"
render json: product
end
Si l'objet (product
dans l'extrait ci-dessus) est nil
, vous pouvez voir le NoMethodError
signalé ci-dessus en raison de nil.read_attribute_for_serialization
être appelé.
J'ai résolu mon problème immédiat en changeant le sérialiseur personnalisé en RecordDetailSerializer et en l'appelant à partir de ma méthode show dans le contrôleur. Lorsque j'ai supprimé l'inclusion @JMazzy a suggéré que cela fonctionnait toujours. Il y a encore quelque chose de foutu. Si j'utilise la méthode personnalisée dans la méthode d'index:
def index
@records = Record.order('title')
render :json => @records, serializer: RecordDetailSerializer
end
J'obtiens l'erreur sur l'ID manquant indiqué au bas de ma question ci-dessus. Cependant, lorsque je l'utilise dans ma méthode d'exposition:
def show
@record = Record.find(params[:id])
render :json => @record, serializer: RecordDetailSerializer
end
Si je supprime le champ de problème, le champ suivant de la liste devient le problème. Ce n'est plus un problème pour moi car je peux toujours limiter les sérialiseurs personnalisés à un élément individuel.