Jared Murphy Jared Murphy - 9 months ago 29
Ruby Question

Active Record how to preload join for scoped relationships

Thanks for taking a look at my question. I'm working on a Rails 5 API and am having trouble with a specific query.

My db has 2 models - players and battles. The battles table has 2 foreign key references to players as 'winner_id' and 'loser_id'. I also have a scope to include the winner and loser called 'with_results':

# models/battle.rb
class Battle < ApplicationRecord

belongs_to: winner,
class_name: "Player",
foreign_key: "winner_id"

belongs_to: loser,
class_name: "Player",
foreign_key: "loser_id"

scope :with_results, -> { includes(:winner, :loser) }

end


So what I am trying to achieve is getting the battle table, the winner's Player table, and the loser's Player table in one query.

In the rails console I have tried a few things:

Battle.first
# => returns just the battle table with the id's of the winner and loser

Battle.with_results.first
# => returns the same as `Battle.first`

Battle.first.winner
# => returns the winner's Player table

Battle.first.loser
# => returns the loser's Player table

Battle.joins(:winner, :loser).first
# => returns the same as `Battle.first`


Again, what I am trying to do is get the battle, the winner, and the loser in just one query so I can send out the JSON for it. Is there a way to preload the winner and loser with a scope so that I can have it all in one query?

Thanks for any advice!

Answer Source

You're almost there! Just tell to_json to include associations. For example:

Battle.with_results.first.to_json(include: [:winner, :loser])