I have an author that has many books and a book that belongs to an author in an rails 7 api. I am using "jsonapi-serializer", "~> 2.2" to try and get the author and their books. When I look at the json file, I get this:
{
"id": "1",
"type": "author",
"attributes": {
"id": 1,
"fname": "John",
"lname": "Doe"
},
"relationships": {
"books": {
"data": [
{
"id": "1",
"type": "books"
},
{
"id": "2",
"type": "books"
},
{
"id": "3",
"type": "books"
},
{
"id": "4",
"type": "books"
},
{
"id": "5",
"type": "books"
}
]
}
}
}
I want to expand what is in relationships to show the full information or at least customize it so that it shows something like id, name, release_year rather than just id and type. I don’t want to have to make another database query to get the books.
The AuthorSerializer looks like this:
class AuthorSerializer
include JSONAPI::Serializer
attributes :id, :fname, :lname
has_many :books
end
The BookSerializer looks like this:
class BooksSerializer
include JSONAPI::Serializer
attributes :id, :name, :release_year, :awards, :genre, :price, :blurb, :isbn
belongs_to :author
end
The Author controller looks like this:
class AuthorController < ApplicationController
before_action :set_author, only: %i[ show update destroy ]
# GET /authors
def index
@authors = Author.includes(:books).all
render json: AuthorSerializer.new(@authors)
end
# GET /authors/1
def show
render json: AuthorSerializer.new(@author)
end
# POST /authors
def create
@author = Author.new(hospital_params)
if @author.save
render json: @author, status: :created, location: @author
else
render json: @author.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /authors/1
def update
if @author.update(author_params)
render json: @author
else
render json: @author.errors, status: :unprocessable_entity
end
end
# DELETE /authors/1
def destroy
@author.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_author
@author= Author.find(params[:id])
end
# Only allow a list of trusted parameters through.
def author_params
params.require(:author).permit(:id, :fname, :lname, :avatar[])
end
end
2
Answers
There are lots of ways you can get associated data from the associated model in Ruby on rails:
I just share two ways:
example:
More details: See Here
If you have any confusion, let me know. Thank you.
What you are asking for violates the JSON:API spec.
As you can see a Resource Identifier cannot contain anything more than
type
,id
, andmeta
(other than non persisted objects which must containlid
in place ofid
)The
jsonapi-serializer
gem strictly adheres to the spec and only returns the "Resource Identifier Objects" i.e.type
andid
(Code Source)You could use
AuthorSerializer.new(@authors, include: [:books])
which will add theBook
objects to theincluded
member but it is definitely not the cleanest representationExample: