Question

Question

Below I give my current API result, however, given the SQL that is executed it isn't my Expected or Desired Result. Can anyone assist me in getting the second SQL queries results instead of the first?

Models

console_game.rb

class ConsoleGame < ActiveRecord::Base
    self.table_name = 'console_game'
    self.primary_key = :id

    has_many :configurations, :class_name => 'Configuration'
end

configuration.rb

class Configuration < ActiveRecord::Base
    self.table_name = 'configuration'
    self.primary_key = :id
end

API

resource :configuration do
  desc "Finds all configurations associated with a game."
  params do
    requires :game, type: String, desc: "Game search.", documentation: { example: 'Battlefield 3' }
  end
  route_param :game do
    get do
      ConsoleGame.where(value: 'Battlefield 3').includes(:configurations)
    end
  end
end

Debug Console

D, [2014-05-06T15:11:59.071493 #31068] DEBUG -- : ConsoleGame Load (0.4ms) SELECT console_game.* FROM console_game WHERE console_game.value = 'Battlefield 3' D, [2014-05-06T15:11:59.073289 #31068] DEBUG -- : Configuration Load (0.3ms) SELECT configuration.* FROM configuration WHERE configuration.console_game_id IN (2) 127.0.0.1 - - [06/May/2014 15:12:08] "GET /configuration/game HTTP/1.1" 200 34 25.9740

Result - get /configuration/game

[
    {
        id: 2,
        value: "Battlefield 3"
    }
]

Desired Result - get /configuration/game

[
    {
        id: 2,
        value: "x",
        device: 4,
        system: null,
        console_game_id: 2,
        creator: "yrdy",
        created_date: null,
        positive_votes: 0,
        negative_votes: 0
    },
    {
        id: 4,
        value: "ffds",
        system: 2,
        console_game_id: 2,
        creator: "gdfs",
        created_date: null,
        positive_votes: 0,
        negative_votes: 0
    }
]

Note: There are a lot of foreign indexes on this table and i'd like to resolve them all but perhaps thats for another day.

Result of ConsoleGame.where(value: 'Battlefield 3').includes(:configurations).as_json(include: :configurations)

[
    {
        id: 2,
        value: "Battlefield 3",
        configurations: [
            {
                id: 2,
                value: "ffds",
                device: 4,
                system: null,
                console_game_id: 2,
                creator: "yrdy",
                created_date: null,
                positive_votes: 0,
                negative_votes: 0
            },
            {
                id: 4,
                value: "x",
                device: 4,
                system: 2,
                console_game_id: 2,
                creator: "gdfs",
                created_date: null,
                positive_votes: 0,
                negative_votes: 0
            }
        ]
    }
]
Was it helpful?

Solution

Does this work?

class ConsoleGame < ActiveRecord::Base
  #self.table_name = 'console_game'
  #self.primary_key = :id

  has_many :configurations #, :class_name => 'Configuration'
end

class Configuration < ActiveRecord::Base
  #self.table_name = 'configuration'
  #self.primary_key = :id
  belongs_to :console_game #, class_name: "ConsoleGame", primary_key: 'console_game_id', foreign_key: 'id'  #added relationship for ConsoleGame
end

resource :configuration do
  desc "Finds all configurations associated with a game."
    params do
      requires :game, type: String, desc: "Game search.", documentation: { example: 'Battlefield 3' }
    end
    route_param :game do
      get do
        #Search Configurations based on console game
        Configuration.joins(:console_game).where(console_game:{value: 'Battlefield 3'})
      end
    end
end

Better yet add a scope

class Configuration < ActiveRecord::Base
  #self.table_name = 'configuration'
  #self.primary_key = :id
  belongs_to :console_game #, class_name: "ConsoleGame", primary_key: 'console_game_id', foreign_key: 'id'  #added relationship for ConsoleGame
  scope :by_game,->(game){
           #verbosely
           #game_ids = ConsoleGame.where(value: game).pluck(:id)
           #where(console_game_id: game_ids)
           #one line
           joins(:console_game).where(console_game:{value: game})
           }
end    

Use as

Configuration.by_game('Battlefield 3')

EDIT

I have commented out the lines that are not needed because they are implied by design

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top