1

I'm creating an api in ruby on rails, I have a couple tables events, artists, and countries, events has artist_id which is a foreign key to the id field in artists. Events also has country_id, which is a foreign key to country id field. When a user asks my api for /events/artist/:artist_id, I want to return json results in the form of

[
{
    "id":1,
    "type":"festival",
    "artist":{
      "id":1,
      "name":"doesnt matter"
    },
    "country":{
      "id":1,
      "name":"cambodia"
    }
]

I'm unsure however how to include nested objects in my json response, would I do multiple queries and some how inject them into my json response? I am sure there are better ways to set up my database for this as well and I'm open to suggestions but an event can only have one artist and be in one country, though countries can have multiple events. The core of my issue is not the database though, I cant find any information how to nest queries in my response.(Which is I think what I need to do) ruby on rails - 6.0.2, ruby 2.7.1

1 Answer 1

3

You can use as_json method on your events.

It's fully customizable:

@artist = Artist.find(params[:artist_id])

@artist.events.as_json(
  only: [:id, :type],
  include: [
    artist: {only: [:id, :name]},
    country: {only: [:id, :name]}
  ]
)

However, this would generate one query for Event.all plus two queries for each event. To preload all artists and countries and do only 3 queries you can do:

@artist.events.includes([:artist, :country]).as_json(
  only: [:id, :type],
  include: [
    artist: {only: [:id, :name]},
    country: {only: [:id, :name]}
  ]
)

In addition to that, you shouldn't return artist json for each event if the artist is always the same. (since you searched for events associated to the same artist). You would get useless data duplication. You may try to format your data the other way:

@artist.as_json(
  only: [:id, :name],
  include: [
    events: {
      only: [:id, :name],
      include: {
        country: {only: [:id, :name]}
      }
    }
  ]
)
Sign up to request clarification or add additional context in comments.

4 Comments

Ahh gotcha, thanks, I guess its worth mentioning a get request to /events/artists/:artist_id is supposed to give back all events that the artists with the requested id has preformed at, and not all events.
also, does include use the foreign keys to find the associated artist and country? How does it get that information if the only thing in an event tying it to a artist and country is artist_id, and country_id.
Yes it does find the associated artist and country using foreign key. I also edited my answer to scope only for that artist
To understand what include does, try the different solutions I gave you in the console, and look at the SQL requests which are generated. It's worth a thousand words ;)

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.