API Get Request to pull data from an online database This code gets detailed information about a particular game from an online database using an API Get request. The question I have doesn't pertain to the request but is more about the code itself. The code works. I just think it is long for what needs to be done though. I was wondering if this code is able to be refactored because there are a few places the code just looks the same. I have been trying for last couple of days to get this done with no avail. Any help will be appreciated.

def self.get_game_details(game_selection)
    if Game.all[game_selection.to_i - 1].description == nil
        response = RestClient.get("#{DETAIL_URL}#{Game.all[game_selection.to_i - 1].slug}", headers = {"x-rapidapi-host" =&gt; ENV["HOST"], "x-rapidapi-key" =&gt; ENV["API_KEY"]})
        data = JSON.parse(response.body)

        Game.all[game_selection.to_i - 1].description = data["description"]
        Game.all[game_selection.to_i - 1].released = data["released"]
        Game.all[game_selection.to_i - 1].metacritic_rating = data["metacritic"] unless data["metacritic"] == nil # default to 0 if no data

        data["ratings"].each do |rating|
            case rating["title"]
            when "recommended"
                Game.all[game_selection.to_i - 1].recommended_rating = rating["percent"] unless rating["percent"] == nil # # default to 0.0 if no data
            when "exceptional"
                Game.all[game_selection.to_i - 1].exceptional_rating = rating["percent"] unless rating["percent"] == nil # # default to 0.0 if no data
            when "meh"
                Game.all[game_selection.to_i - 1].meh_rating = rating["percent"] unless rating["percent"] == nil # # default to 0.0 if no data
            when "skip"
                Game.all[game_selection.to_i - 1].skip_rating = rating["percent"] unless rating["percent"] == nil # # default to 0.0 if no data
            end
        end
    end
end
My approach to your code:

# If this data isn't going to change, using constants would be good enough
HEADERS = { 'x-rapidapi-host' =&gt; ENV['HOST'],
            'x-rapidapi-key' =&gt; ENV['API_KEY'] }.freeze

def self.get_game_details(game_selection)
  # If Game is an ActiveRecord class, probably you should modify this to look
  # for the specific record instead of loading everything with .all
  # If is just a PORO, forget what I said.
  game = Game.all[game_selection.to_i - 1]
  return if game.description.present?

  response = RestClient.get("#{DETAIL_URL}#{slug}", HEADERS)
  data = JSON.parse(response.body)
  game.details = data
end

class Game
  ALLOWED_RATINGS = %w[recommended exceptional meh skip].freeze

  # Moved most of the assigning logic into the Game class. This is debatible as
  # I could use a Service class or another pattern for this, but as I don't
  # know your code's nature, to me looks like the quickest way.
  def details=(data)
    self.description = data['description']
    self.released = data['released']
    # .presence will return nil for blank strings, empty arrays, etc, then with
    # || you will default the value to 0, as:
    #
    #   nil || 0 # =&gt; 0
    self.metacritic_rating = data['metacritic'].presence || 0

    data['ratings'].each { |rating| self.rating = rating }
  end

  def rating=(rating)
    # .send method can run any method of this class, so better to check if the
    # value is valid first
    return unless ALLOWED_RATINGS.include? rating['title']

    send("#{rating['title']}_rating=", rating['percent'].presence || 0.0)
  end
end