James White
James White

Reputation: 535

Rails API: Adding array of objects to json return

I'm using the built-in API with Rails 5.

I'm learning to write APIs with Rails and I'm trying to figure out how to add a property to my json return that is an array of objects.

I've got a model for Users and Posts.

What I would like to do is return all the posts associated with a users.

What I've done is in posts_controller.rb I've got a method that gets the userID form the URL and returns json that looks like:

[{"id":1,"content":"My first post!","user":{"id":1,"firstname":"Jody","lastname":"White","email":"[email protected]","fullname_firstname_first":"Jody White"}},{"id":2,"content":"Rails School is awesome!","user":{"id":1,"firstname":"Jody","lastname":"White","email":"[email protected]","fullname_firstname_first":"Jody White"}}]

But what I want is to return that looks like this:

{
    firstname: "Jody",
    lastname: "White",
    email: "whatever",
    posts: [{
        "id":1,"content":"My first post!"
        },
        {
            "id":2,"content":"Rails School is awesome!"
        }
    ]
}

How do I go about, or can I, getting the data to return like that?

user.rb model

class User < ApplicationRecord
  attr_accessor :fullname_firstname_first

  has_many :posts

  def fullname_firstname_first
    fullname_firstname_first = firstname + " " + lastname
  end
end

post.rb model

class Post < ApplicationRecord
  belongs_to :user
end

users_controller.rb

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :update, :destroy]

  # GET /users
  def index
    @users = User.all
    render json: @users, include: :posts
  end

  # GET /users/1
  def show
    @user = User.find(params[:id])
    render json: @user, include: :posts
  end
end

Upvotes: 4

Views: 2830

Answers (1)

Christian-G
Christian-G

Reputation: 2361

Assuming you defined this structure:

class Post < ApplicationRecord
  belongs_to :user
end

class User < ApplicationRecord
  has_many :posts
end

You could achieve a structure like you wanted with the Active Record serialization method to_json. The use would be in a respond_to block in your controller.

format.json { render json: @users, include: :posts }

So your UsersController would look something like this:

class UsersController < ApplicationController
  def index
    # all users with all their posts 
    @users = User.all
    respond_to do |format|
      format.json { render json: @users, include: :posts }
    end
  end

  def show
    # single user and their posts
    @user = User.find(params[:id])
    respond_to do |format|
      format.json { render json: @user, include: :posts }
    end
  end
end

Update

Instead of using the repond_to block you can alternatively use:

render json: @users, include: :posts

Your controller will then look like:

class UsersController < ApplicationController
  def index
    # all users with all their posts 
    @users = User.all
    render json: @users, include: :posts
  end

  def show
    # single user and their posts
    @user = User.find(params[:id])
    render json: @user, include: :posts
  end
end

Upvotes: 4

Related Questions