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

J'obtiens le message d'erreur:

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

L'erreur est sur la troisième ligne de l'extrait.

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

C'est une autre sérialiseur pour le contrôleur RecordsContrller. L'autre, 'RecordsSerializer, fonctionne très bien.

Une recherche sur cette erreur a quelques solutions. Certains n'étaient pas claires quant à l'endroit où on pourrait ajouter le code. Un autre a suggéré d'ajouter:

alias :read_attribute_for_serialization :send

à la classe où l'erreur se produit. Il n'a pas de travail pour moi. J'ai aussi regardé à travers le joyau de la documentation. J'ai trouvé un exemple de l'utilisation de sérialiseur:. Il était clair tout autre code était nécessaire.

Je suis en utilisant Ruby 2.3.0 et les Rails 5.0.0.

Contrôleur

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

Modèle

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

Schéma pour les Enregistrements

  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

J'ai juste remarqué, la clé primaire, id, n'apparaît pas dans le schéma. Je le vois dans Sequel Pro quand j'ai vue la structure de la table.

Mise à jour

J'ai ajouté le code suggéré par @JMazzy. Maintenant, je reçois l'erreur:

<NoMethodError: undefined method `id' for #<Record::ActiveRecord_Relation:0x007faa8005a9d8>\nDid you mean?  ids>
N'oubliez pas de laisser Record.where('artist_id = ' + params[:artist_id]) dans la production, car il pourrait ouvrir votre application à l'Injection SQL. Utilisation: Record.where(artist_id: params[:artist_id]) ou Record.where('artist_id = ?', params[:artist_id]) à la place.

OriginalL'auteur curt | 2016-07-21