7

I am using gem rspotify to access spotify's api in my rails app. The rails version is 6.0.4 but most importantly the Ruby version is 3.0.0

I keep getting this error "undefined method `encode' for URI:Module" when I try to call the api methods. I have to stress that I do not get this error when I downgrade to Ruby 2.6.3. It seems like Ruby 3.0.0 has not support for URI encode. My users controller is the code sample below. I get the error with spotify_user.country and other api methods.

class UsersController < ApplicationController
  skip_before_action :authenticate_user!, only: [ :spotify]

  def spotify
    spotify_user = RSpotify::User.new(request.env['omniauth.auth'])
    spotify_user.country
  end
end

In config/application.rb

RSpotify::authenticate(ENV['SPOTIFY_CLIENT_ID'], ENV['SPOTIFY_CLIENT_SECRET'])

In devise.rb, I have

require 'rspotify/oauth'

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :spotify, ENV['SPOTIFY_CLIENT_ID'], ENV['SPOTIFY_CLIENT_SECRET'], scope: 
  'user-read-email playlist-modify-public user-library-read user-library-modify'
end

I will like to know if there is a solution for the error that does not involve downgrading the ruby version

Hakeem Baba
  • 647
  • 1
  • 12
  • 32

3 Answers3

14

I upgraded from Ruby 2.4.5 to Ruby 3.0.2 and the solution for me was to replace

URI.encode

with

CGI.escape
Dave
  • 15,639
  • 133
  • 442
  • 830
  • 3
    Thanks, But they are not completely interchangeable https://stackoverflow.com/questions/2824126/whats-the-difference-between-uri-escape-and-cgi-escape – Fangxing Apr 07 '22 at 02:41
5

URI.encode was an alias for URI.escape that was in turn considered (and reported) obsoleted for quite a while.

It would be better to see the backtrace for the error you ask about, but I guess it fails here.

As you can see here, RSpotify is not consistent and uses URI.encode in one place and Addressable::URI.encode in another. Chances are this was a conscious decision but at first glance it looks just like an accidental thing.

There are a couple of solutions for your problem:

  1. Fork RSpotify, fix the issue (replace all occurrences of URI.encode with Addressable::URI.encode, for example) and create a PR to upstream. You can use your fixed fork in the meantime, if in a rush with the upgrade.

  2. You can monkey-patch URI itself adding a removed encode method back. Not a good idea at all, but still an option...

  3. Replace RSpotify with some other client. The most involving one so put here just for completeness :)

Dave
  • 78
  • 6
Konstantin Strukov
  • 2,899
  • 1
  • 10
  • 14
1

In pure Ruby, for Ruby 3.X:

URL-encode for whole URL:

URI::Parser.new.escape

URL-encode for URL component:

CGI.escape

For examples, see yard doc here and tests here.

noraj
  • 3,964
  • 1
  • 30
  • 38