2009-01-05 7 views
8

J'essaie de créer un objet ActiveRecord via une requête JSON. Cependant, le contrôleur ne parvient pas à définir les variables passées dans les paramètres de l'objet nouvellement créé. Par exemple, un objet personne a deux champs: prénom et nom.Le contrôleur Rails n'accepte pas JSON?

Le JSON généré par la fonction JSON.stringify de la bibliothèque JSON.org produit:

{"firstname" : "Joe" , "lastname" : "Bloggs"} 

Cependant, le contrôleur attend le JSON être sous la forme:

{ "Person" : {"firstname" : "Joe" , "lastname" : "Bloggs"} } 

Je suis conscient que dans le cours normal des événements (pour les requêtes HTTP), les paramètres de la requête sont imbriqués sous le nom de classe du modèle en cours de création.

La création action dans le contrôleur est:

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 

Quelle serait la façon la plus nette du contrôleur pour traiter les demandes JSON comme produit? Ou comment générez-vous des "JSON" JSON à partir d'objets Javascript pour les transmettre à vos contrôleurs?

TIA, Adam

Répondre

4

Si vous êtes passer un hachage de tous les paramètres de la personne (plutôt que d'un hachage imbriquée avec « personne » comme la clé), alors vous devriez juste être capable de faire @person = Person.new(params).

+0

Cela fonctionnerait-il toujours pour les requêtes HTML standard ou devrais-je refactoriser les requêtes JSON dans une méthode séparée? – apchester

+0

Non. Vous devriez vraiment réécrire vos requêtes JSON pour transmettre le même type de paramètres que ceux qui seraient passés via HTML. –

+0

Merci Zach, Je pensais autant, mais je voulais être sûr de la meilleure pratique. Cheers, Adam – apchester

0

Alternativement, Person.new(params.reject{|k,v| k != "firstname" || k != "lastname"}) ferait dans votre Ruby.

...

Person.new({:firstname => params[:firstname], :lastname => params[:lastname]}) - cela fonctionne en fait

Voici une solution plus FutureProof:

Person.new(params.reject{|k,v| not Person.column_names.include?(k) }) 
+0

Ce qui nécessite que vous configuriez correctement vos attributs "protected", donc quelqu'un ne peut pas passer: isAdmin => true. –

0

Une idée pour permettre l'entrée JSON plat tel que { "prenom": "Joe", "lastname": "Bloggs"} et le type imbriqué que vous obtenez avec un formulaire HTML serait:

@person = Person.new(params[:person] || params) 

respond_to do |format| 
    .. 
end 
1

Quant à ActiveRecord 3.0.7, vous pouvez simplement ajouter

self.include_root_in_json = false 

à votre modèle (person.rb) pour se débarrasser de la racine ({ "Personne": ") partie.