delight.fm: day 10

Persisting… a hash

A couple days ago, I was stuck with an issue that I was having integrating some third-party code into my project. Happy to say I got unstuck! 🎉

I’m retrieving user details from Spotify using a gem called rspotify. Rspotify provides a hash of the necessary user information that you can store. Then you can recreate your user information and make additional calls to the Spotify API later as needed.

I was able to make API calls just fine when I first authenticated with Spotify, but I was having trouble reconstituting my user in a later method. I found the issue by creating a second user from the hash. When I realized that the second user object could connect to the API without issue, it was obvious that I wasn’t storing my hash correctly in the database.

The problem turned out to be that I was using the postgres hstore column type to store my user hash. hstore is a special data type for storing hashes, but the problem was that my hash contained objects that needed to be rebuilt. I switched my column type to text and added the serialize method to my class and it’s working well now.

Here’s the relevant code:

# controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
spotify_user = RSpotify::User.new(request.env['omniauth.auth'])
user = User.find_or_create_from_spotify(spotify_user)
user.update_albums
...
end
end

end
# models/user.rb
class User < ApplicationRecord
serialize :rspotify_hash, Hash
  ...
  def update_albums
spotify_user = RSpotify::User.new(rspotify_hash)
albums = spotify_user.saved_albums
# it works!
...
end
  def self.find_or_create_from_spotify(spotify_user)
user = find_or_initialize_by(spotify_id: spotify_user.id)
user.update_attributes!(rspotify_hash: spotify_user.to_hash)
user
end
  ...
end

Don’t give up when you get stuck. Break the problem down and try to understand each part. Double-check your assumptions. Realize that there is always an answer to why your code is breaking and that if you’re persistent, you can find it.