Skip to content

Instantly share code, notes, and snippets.

@jaredlt
Last active August 2, 2019 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredlt/f41704ada3f383016e90d42c4ebc5422 to your computer and use it in GitHub Desktop.
Save jaredlt/f41704ada3f383016e90d42c4ebc5422 to your computer and use it in GitHub Desktop.

Why classes are cooool!!11

  • In my app I have a lot of objects that represent an album.
  • Until recently, I was using a generic hash for what I needed
  • eg.
album = {
  album_name: "Pure Heroine (Deluxe)",
  artist_name: "Lorde",
  url: "https://music.apple.com/gb/album/pure-heroine/1440818584?uo=4&at%0D=1010lxMt%0D",
  tracks: 10,
  price: 990,
  cover: "https://is5-ssl.mzstatic.com/image/thumb/Music128/v4/17/3c/b3/173cb326-63d7-3936-6302-33848d5caecd/source/200x200bb.jpg",
  id: 1440818584,
  site: :itunes
}
  • This worked for me fine
  • If I need to get a value, I would just grab it from the hash in the normal way
album_name = album[:album_name]
# >> Pure Heroine (Deluxe)
  • If I needed to do something to the album
  • like extract 'Deluxe' from the album_name and set a flag
  • I would create a method
def normalize(album)
  if album[:album_name].end_with?(" (Deluxe)")
    # update album_name to be name without " (Deluxe)"
    # set new k/v of album[:deluxe] = true
  end
  return album
end

normalized_album = normalize(album)
normalized_album[:album_name]
# >> Pure Heroine
normlized_album[:deluxe]
# >> true
  • Often I'd need to grab the artist name and album to use as a search phrase
search_keywords = "#{album[:artist_name]} #{album[:album_name]}"
# >> "Lorde Pure Heroine"
  • Doing this is perfectly fine
  • But sometimes I would create an album using the wrong key value
  • eg. 'album:' instead of 'album_name'
  • This would break the methods eg. normalize
  • Also, it started to become annoying to keep wrapping the album hash in methods that you had to put in front of it ie. normalize(album)
  • I started thinking if there was a better way
  • ideally, you want to take the album and then do something to it. Maybe... album.normalize
  • So I created an Album class
  • This standardises what value types the object can have ie. will error imediately if I try and create using 'album' instead of 'album_name'
class Album
  include ActiveModel::Model

  attr_accessor :release_name, :artist_name, :url, :site, :tracks, :price, :deluxe, :explicitness, :cover, :id, :artist_id
  def initialize(release_name, artist_name, url, site)
    @release_name = release_name
    @artist_name = artist_name
    @url = url
    @site = site
  end
end

album = Album.new("Pure Heroine (Deluxe)", "Lorde", "https://music.apple.com/gb/album/pure-heroine/1440818584?uo=4&at%0D=1010lxMt%0D", :itunes)
  • Now you can reference the values you want using a '.'
  • A bit nicer than the has approach, but not that different
album.release_name # >> Pure Heroine (Deluxe)
album.artist_name # >> Lorde
album.url # >> https://music.apple.com/gb/album/pure-heroine/1440818584?uo=4&at%0D=1010lxMt%0D
album.site # >> :itunes
  • The real benefit comes with the methods that I can include in the class
  • eg
class Album
  include ActiveModel::Model

  attr_accessor :release_name, :artist_name, :url, :site, :tracks, :price, :deluxe, :explicitness, :cover, :id, :artist_id
  def initialize(release_name, artist_name, url, site)
    @release_name = release_name
    @artist_name = artist_name
    @url = url
    @site = site
  end

  def normalize
    if self.album_name.end_with?(" (Deluxe)")
      # update album_name to be name without " (Deluxe)"
      # set new k/v of album[:deluxe] = true
    end
    return album
  end


  def artist_release_keywords
    "#{self.artist_name} #{self.album_name}"
  end

  private
    # add methods here that the other methods above might use
    # keeps the main methods clean and readable
    # while keeping all relevant stuff together
end

album.normalize
# >> 
# album_name: "Pure Heroine"
# artist_name: "Lorde"
# url: "https://music.apple.com/gb/album/pure-heroine/1440818584?uo=4&at%0D=1010lxMt%0D"
# site: :itunes
# deluxe: true

album.artist_release_keywords # >> Lorde Pure Heroine
  • You can also now easily add validation
  • eg. ensure that 'tracks' is an integer
  • Because I scrape some results from html, they return as String and I usually forget to convert them which produces errors in other code I use
  • You could detect errors early with class validation
  • (I haven't actually explored this yet)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment