Reputation: 535
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
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