Reputation: 97
A model(FirstModel) in my rails app has a has_many relationship with another model(Item).
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
Item itself belongs :item_thing through a polymorphic association. A method on FirstModel returns an array of "items", not the join model object(which is of class Item), but the item_thing of each Item object, and therefore it is an array of objects of different classes (checked in rails console, and the method returns the array just fine)
class Item < ActiveRecord::Base
belongs_to :item_thing, :polymorphic => true
end
In my show.json.jbuilder for FirstModel, I want to take that array of "items" and use different templates based on which class the item belongs to. The following file path is "views/api/items/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
The car and book template paths are "views/api/cars/show.json.jbuilder" and "views/api/books/show.json.jbuilder.
When I get the json from the above template the name of the FirstModel object is visible, items array is empty, whereas I am trying to get an array of hashes for each item, rendered through its respective template.
Thank you for helping!
Upvotes: 1
Views: 2467
Reputation: 303
You can probaly just do something like the code below if you name your items and partials correctly.
json.items @item.item_array do |item|
json.partial! "api/#{item.class.to_s.pluralize.downcase}/show"
end
Alternatively you could use a case statement on item.class.to_s
, or as one of the other answers suggested, use the class actual class instead of the class name as a string.
Upvotes: 3
Reputation: 26768
I think your code will work if you change your class strings to actual class names.
I.e. User
and not "User"
.
Or you could keep the strings and use .class.to_s
, which will return "User"
for a user record.
If you're interested in metaprogramming, the constantize
, camelify
and underscore
methods from activesupport might be useful down the line.
Upvotes: 2