Il controller Rails non accetta JSON?
-
03-07-2019 - |
Domanda
Sto cercando di creare un oggetto ActiveRecord tramite una richiesta JSON. Tuttavia, il controller non riesce a impostare le variabili passate nei parametri nell'oggetto appena creato. Ad esempio, un oggetto persona ha due campi: nome e cognome.
Il JSON generato dalla funzione JSON.stringify della libreria JSON.org produce:
{"firstname" : "Joe" , "lastname" : "Bloggs"}
Tuttavia, il controller si aspetta che JSON sia nel formato:
{ "Person" : {"firstname" : "Joe" , "lastname" : "Bloggs"} }
Sono consapevole che nel normale corso degli eventi (per richieste HTTP) il i parametri per la richiesta sono nidificati sotto il nome della classe del modello in fase di creazione.
L'azione di creazione nel controller è:
def create
@person = Person.new(params[:person])
respond_to do |format|
if @person.save
flash[:notice] = 'Person was successfully created.'
format.html { redirect_to(@person) }
format.xml { render :xml => @person, :status => :created, :location => @person }
format.json { render :json => @person, :status => :created, :location => @person }
else
format.html { render :action => "new" }
format.xml { render :xml => @person.errors, :status => :unprocessable_entity }
format.json { render :json => @person.errors, :status => :unprocessable_entity }
end
end
end
Quale sarebbe il modo più accurato per il controller di elaborare JSON richieste come generate? O in alternativa come si genera "corretto" JSON da oggetti Javascript per il passaggio ai controller?
TIA, Adam
Soluzione
Se stai semplicemente passando un hash di tutti i parametri persona (piuttosto che un hash nidificato con " person " come chiave), dovresti essere in grado di fare @person = Person.new ( params)
.
Altri suggerimenti
Come per ActiveRecord 3.0.7, puoi semplicemente aggiungere
self.include_root_in_json = false
al tuo modello (person.rb) per sbarazzarti della parte root ({" Person ": ").
In alternativa,
Person.new (params.reject {| k, v | k! = " nome " || k! = " cognome "})
farebbe nel tuo Ruby....
Person.new ({: firstname = > params [: firstname],: lastname = > params [: lastname]})
- funziona davvero
Ecco una soluzione più a prova di futuro:
Person.new(params.reject{|k,v| not Person.column_names.include?(k) })
Un'idea per consentire un input JSON piatto come {" nome " ;: " Joe " ;, " cognome " ;: " bloggs "} e il tipo nidificato che ottieni con un modulo HTML sarebbe:
@person = Person.new(params[:person] || params)
respond_to do |format|
..
end