1

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!

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.