2014-12-30 15 views
7

Sto costruendo un Rest API utilizzando rails-api e active-model-serializer per filtrare facilmente i campi richiesti nel JSON. Sto anche usando l'associazione has_one in questi serializzatori. Tutto quello che volevo sapere è come specificare un nome di chiave diverso per l'attributo has_one.Utilizzo di un nome chiave diverso per un attributo di associazione in rails api serializzatore modello attivo

Cioè, ho due modelli dire: Employee e Address, e c'è un has_one :address nel dire EmployeeSerializer. La risposta che ottengo è:

{ 
    id: 1, 
    address: { 
    street: "some_street", 
    city: "some_city" 
    } 
} 

Ma mi piacerebbe ottenere la seguente risposta:

{ 
    id: 1, 
    stays: { 
    street: "some_street", 
    city: "some_city" 
    } 
} 

Ho provato ad utilizzare has_one :address, :key => :stays, ma questo non sembra funzionare.

+0

Quale versione di AMS si usa? Non ho familiarità con la base di codice, ma da un rapido sguardo l'argomento 'key' sembra non essere stato incluso in tutti i recenti. Come soluzione, prova a definire 'has_one: stays' insieme a' def stays; object.address; FINE'. – janfoeh

+0

@janfoeh Sto usando la versione 0.9.0.Inoltre sto usando un serializzatore differente per l'associazione. cioè, has_one: indirizzo, chiave: 'status', serializzatore: MyAddressSerializer'. Sta prendendo gli attributi da 'MyAddressSerializer' ma la chiave di attributo è ancora' address' – swaroopsm

+0

Ah. Se leggo correttamente le [modifiche tra 0.9.0 e 0.9.1] (https://github.com/rails-api/active_model_serializers/compare/v0.9.0...v0.9.1), l'argomento è stato chiamato 'embed_key 'in 0.9.0, non' chiave'. – janfoeh

risposta

7

È possibile definire stays come uno degli attributi che si desidera avere nella vostra JSON.

Naturalmente, il serializzatore andrà all'istanza del modello e non troverà un attributo nel modello con quel nome. Quindi, sarà seduto lì a grattarsi la testa su cosa nel mondo dovrebbe essere il valore di :stays.

Ok, perché è possibile definire un metodo di istanza nel serializzatore che indica esattamente quale dovrebbe essere quel valore. In quel metodo di istanza, ti viene assegnata la variabile object, che è l'oggetto che il serializzatore sta attualmente elaborando. object.address pertanto sarà l'istanza Address.

Una volta ottenuta l'istanza dell'indirizzo, è possibile creare un'istanza di un serializzatore che utilizzerà tale istanza per visualizzare i campi delineati al suo interno. Credo che lo root: false sia necessario in quanto altrimenti l'attributo :stays (o qualunque sia il serializzatore che ti restituisce in questo caso) verrà visualizzato all'interno di un altro attributo :stays.

vostro serializzatore finale per Employee dovrebbe apparire come segue:

class EmployeeSerializer < ActiveModel::Serializer 
    attributes :id, :name, :stays 

    def stays 
    MyAddressSerializer.new(object.address, root: false) 
    end 

end 
+0

Aggiungere una descrizione al motivo per cui farà il lavoro. È di qualità molto bassa e non si adatta molto bene allo stile SO Q & A ed è stato contrassegnato come post di bassa qualità. – Cheesebaron

+0

@Cheesebaron come è? :) – Kalman

+0

Molto meglio :) – Cheesebaron

3

@janfoeh è proprio su. Ho appena provato questo in versione 0.8 e funziona bene

  1. gem "active_model_serializers", "~> 0.8.0" nel vostro Gemfile
  2. Uccidi il server
  3. $bundle install
  4. has_one :address, key: "stays"
  5. Avviare il server di back up

Funziona alla grande!

quanto la documentazione per la gemma dice (here), "probabilmente si desidera utilizzare la versione 0.8"

+0

Se uso la versione '0.8.0',' MyAddressSerializer' non funziona in: 'has_one: indirizzo, chiave: 'status', serializzatore: MyAddressSerializer' – swaroopsm

+0

@swaroopsm è 'Indirizzo' sempre serializzato con' MyAddressSerializer'? Se sì, è possibile definirlo su 'Address' stesso con' def active_model_serializer; MyAddressSerializer; end'. – janfoeh

Problemi correlati