2010-12-14 3 views
19

J'ai une étrange situation de modèle de données pour commencer, alors peut-être que toute mon approche est fausse. Voici ce que je fais:RoR imbriqué: include pour inclure des sous-ressources dans to_xml/to_json

J'ai une classe appelée Bird et une classe simple appelée Couleur. D'un point de vue conceptuel, chaque oiseau a deux associations à la couleur, une pour les couleurs masculines et une pour les couleurs féminines. La façon dont j'ai manipulé ceci est d'utiliser un modèle de joint appelé BirdColoration qui appartient à un oiseau et une couleur et a un champ booléen supplémentaire pour dire si la coloration est pour mâle ou femelle. Donc, chaque oiseau a réellement une relation to_many à BirdColoration, ainsi qu'un to_many à Color: à travers BirdColoration. Si cela semble raisonnable, continuez à lire. Sinon, arrêtez-vous et dites-moi pourquoi c'est faux!

Je dois être en mesure de vider la table des oiseaux comme json. Auparavant, quand chaque oiseau avait seulement une association à beaucoup de couleurs, je pouvais simplement utiliser: inclure pour inclure les couleurs de chaque oiseau dans la décharge json. Maintenant, j'inclus les BirdColorations dans la décharge, mais j'ai encore besoin d'obtenir les modèles de couleurs eux-mêmes. Je pourrais inclure séparément les couleurs et les colorations de chaque oiseau, puis les mettre en correspondance tout en analysant, mais je préfèrerais simplement inclure la couleur de chaque couleur directement. Quelque chose comme

 format.json { render :json => @birds.to_json(:include => [{:bird_colorations => :color}, :seasons, :habitats, :image_holders]) } 

Ce qui précède ne fonctionne pas, cependant. Je pense que cela devrait être possible. Quelqu'un peut-il me diriger dans la bonne direction pour savoir comment gérer cela? Pour l'instant, je vais juste inclure la couleur et les colorations de chaque oiseau séparément et les faire correspondre dans l'analyse. Au moins, je sais que ça va marcher.

Merci!

Répondre

51

J'ai trouvé la réponse here. La syntaxe de l'option: include dans to_xml et to_json est différente de celle de la méthode find d'ActiveRecord. Pour inclure des ressources imbriquées de cette manière, vous passez un hachage à la place d'un tableau. L'appel de méthode correcte pour moi ressemble à:

 format.json { render :json => @birds.to_json(:include => {:bird_colorations => {:include => :color}, :seasons => {}, :habitats => {}, :image_holders => {}}) } 

Comparez à celui de ma question pour voir la différence. Pour les ressources pour lesquelles vous ne souhaitez pas inclure de sous-ressources, transmettez simplement un hachage vide comme valeur pour son nom symbolisé.

Vivre et apprendre!

+1

Je voudrais voter plus pour ça !! Merci! – brutuscat

+0

moi aussi @brutuscat. Sauvé mon bacon! – Rots

+0

Le code dans votre question semble tellement plus propre, c'est tellement contre-intuitif. Surtout que si vous n'aviez pas la couleur d'imbrication bird_colorations, l'exemple de questions fonctionnerait. Merci d'avoir posté votre solution. Les rails devraient fixer ceci ... – thatmiddleway

2

Si vous avez une structure JSON complexe, il est préférable de remplacer serializable_hash ou as_json dans votre modèle que d'essayer de le faire via render :json.

donc quelque chose comme

def serializable_hash(options = nil) 
    options ||= {} 
    bird = {:name => name, ...} 
    bird[:seasons] = seasons.serilizable_hash 
    bird[:colors] = ... # whatever complex logic you want to get to the colors 
    bird 
end 

Les deux fonctions juste besoin de retourner un hachage.

+0

Merci! Je vais jeter un coup d'oeil à ça. Si je suis satisfait de la sortie de render: json, y a-t-il une autre raison de surcharger ces méthodes (performance, peut-être)? Toutes choses égales par ailleurs, mon instinct est de laisser la fonctionnalité intégrée prendre soin des choses pour moi. – CharlieMezak

+0

Je ne pense pas que vous obtiendrez une augmentation des performances car render json appelle as_json/serializable_hash en arrière-plan.C'est juste une bonne philosophie de conception appelée «gros modèles, contrôleurs minces», plus élégamment discuté ici: http://stackoverflow.com/questions/2550376/rails-skinny-controller-vs-fat-model-or-should-i- make-mon-contrôleur-anorexique – icecream

Questions connexes