2

First off, I would like to ask for your patience since this question is going to be really noobish. I've tried researching to no avail, as I can't put everything into place.

Anyway, I need to be able to render items in the database I will create as JSON. However, it is nested and I am unsure how would I go about creating the model for it:

{
"name": "name",
"description": "description",
"review": [
    {
        "rating": "rating",
        "content": "content"
    },
    {
        "rating": "rating",
        "content": "content"
    }
]
}

Creating the Database

Do I create two tables first (i.e. Item and Review), like so?

rails g model Item name:string description:string review:string
rails g model Review rating:string content:string

I've read that I need the accepts_nested_attributes_for method, but again, I am unsure how to use it.

class Item < ActiveRecord::Base
  has_many :reviews

  accepts_nested_attributes_for :reviews
end

class Review < ActiveRecord::Base
  belongs_to :item
end

Populating the Database

If by some chance the above is correct, how do I actually populate the database using the console or seed.rb?

Rendering as JSON

This is what I have for non-nested entries:

def index
   @items = Items.all
   render :json => @items.as_json(:except => [:id, :created_at, :updated_at])
end

As you can tell, I am confused and lost. I would very much appreciate any input. Thank you.

1 Answer 1

4

It looks like you're almost there, and are definitely on the right track.

When you create your models, you won't need review:string for Item, but you will need a item_id for Review (to hold the associated Item.id), like such:

rails g create Item name:string description:string
rails g create Review rating:string content:string item_id:integer

The way rails associations work is it will store the item.id for the associated Item record in review.item_id. It will do this automagically, so all you need to do is use them.

To create the association between Review and Item:

new_review = Review.create(rating: 'great', content: 'Wonderfully done')
new_item = Item.create(name: 'My Item', description: 'My Item description')
new_item.reviews << new_review

To access the associated review(s) from Item:

new_item.reviews.each do |review|
    review.rating
    review.content
end

Because it's a has_many relationship, an instance of Item will have a reviews method which returns an array of Review objects that have an item_id matching the current Item.id.

Likewise, an instance of Review will have a item method (note the singular use here), which just returns the single associated Item record object.

Make sense?

Additionally, when you output a record with an association in JSON (as you've done in your example), it should create output close to what your example shows.

Render your JSON as follows:

@items = Item.all
render :json => @items.to_json(:include => [:reviews], :except => [:id, :created_at, :updated_at])
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for your response. I got stuck at storing the newly-made review, unfortunately. It tells me it cannot find the method--undefined method 'reviews'.
have you migrated your database?: rake db:migrate
Make sure you've created the associations like in your example and applied the database migration with rake db:migrate.
@benjaminjosephw Yes, I have.
Item.reviews << new_review is incorrect. You need to associate data with an instance of Item, not on the Item class itself.
|

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.