2016-03-29 2 views
1

Un modèle (FirstModel) dans mon application rails a une relation has_many avec un autre modèle (Item).Utilisation de jbuilder dans des rails pour construire un tableau d'objets avec des classes différentes

class FirstModel < ActiveRecord::Base 

    has_many :items, :dependent => :destroy 

    def item_array 
    a = [] 
    self.items.each do |item| 
     a.push(item.item_thing) 
    end 
    a 
    end 
end 

L'élément lui-même appartient: item_thing via une association polymorphique. Une méthode sur FirstModel retourne un tableau de "items", pas l'objet modèle join (qui est de la classe Item), mais le item_thing de chaque objet Item, et donc un tableau d'objets de différentes classes (cochée dans la console rails, et la méthode retourne le tableau très bien)

class Item < ActiveRecord::Base 
    belongs_to :item_thing, :polymorphic => true 


end 

Dans mon show.json.jbuilder pour FirstModel, je veux prendre ce tableau des « éléments » et utiliser différents modèles basés sur quelle classe l'élément appartient. Le chemin du fichier suivant est "vues/api/articles/show.jbuilder"

json.extract! @item, :name 

json.items @item.item_array do |item| 
    if item.class == 'Book' 
    json.partial! 'api/books/show', item 
    end 
    if item.class == 'Car' 
    json.partial! 'api/cars/show', item 
    end 
end 

Les chemins de voiture et modèle de livre sont "vues/api/voitures/show.json.jbuilder" et « vues/api/Livres /show.json.jbuilder

Lorsque j'obtiens le json du template ci-dessus le nom de l'objet FirstModel est visible, le tableau items est vide, alors que j'essaye d'obtenir un tableau de hashes pour chaque item, rendu par son modèle respectif.

Merci d'aider!

Répondre

2

Je pense que vous Le code r fonctionnera si vous changez les chaînes de votre classe en noms de classe réels.

I.e. User et non .

Ou vous pouvez conserver les chaînes et utiliser .class.to_s, qui renverra pour un enregistrement utilisateur.

Si vous êtes intéressé par la métaprogrammation, les méthodes constantize, camelify et underscore de activesupport pourraient être utiles sur toute la ligne.

2

Vous pouvez probablement faire quelque chose comme le code ci-dessous si vous nommez correctement vos articles et partiels.

json.items @item.item_array do |item| 
    json.partial! "api/#{item.class.to_s.pluralize.downcase}/show" 
end 

Sinon, vous pouvez utiliser une déclaration de cas sur item.class.to_s, ou l'un des autres réponses proposées, utilisez la classe classe réelle au lieu du nom de la classe comme une chaîne.