Today I Learned Notes to self about software development

    Rails Serialize a column

    I never used serialize before since Postgres supports :json and :jsonb columns which are better. It’s still useful that I can still store Hash data in the sqlite db text column— especially if my students, who aren’t using Postgres, want to do complicated stuff like OAuth and need to store some credentials.

    Re: Spotify API

    # in the action of the callback URL...
    spotify_user = RSpotify::User.new(request.env['omniauth.auth'])
    user = User.find_or_create_by({ :spotify_info => spotify_user.to_hash })
    

    #  spotify_info :text
    #
    class User < ApplicationRecord
      serialize(:spotify_info)
    end
    

    OAuth 2 and RSpotify

    I knew that OAuth 2 was replacing OAuth 1, but since I wasn’t actively working on projects that used OAuth 1 I didn’t really internalize it until I was helping someone use the rspotify gem recently and ran into a bunch of issues trying to follow the instructions in the README.

    The README is a trap.

    Even though it appears to have been updated semi-recently, the setup instructions are outdated. I had to reference an issue from 2016 to figure out why. I searched some other errors and found the omniauth upgrade guide which mainly clarified that the auth request needs to be a POST instead of a GET.

    Array#sample accepts an argument

    TIL you can pass an argument to Array#sample to return more than one random element.

    [1,2,3,4,5,6].sample     # => 4
    [1,2,3,4,5,6].sample(3)  # => [2, 4, 5]
    [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative array size
               [].sample     # => nil
               [].sample(3)  # => []
    

    Three things I learned from The Ruby Koans

    Here are (at least) three things I learned from The Ruby Koans:

    Blocks

    I knew how to use blocks for methods that require them (like Array#each) but I didn’t have a grasp on how they worked outside of methods that I was familiar with.

    Ruby blocks are little anonymous functions that can be passed into methods

    Being told that Blocks are just as anonymous functions really helped it click— since I’m familiar with JS anonymous functions. I think the Block-syntax with pipes was just throwing me off 😅

    Lambdas

    Lamdas are a little weird because they’re basically just Blocks that have been defined and haven’t been run yet. You run them with .call.

    say_something = -> { puts "This is a lambda" }
    say_something.call
    

    Procs

    Procs are basically just lambdas. Lambdas are actually just a special kind of Proc.

    proc = Proc.new { |arg| puts arg }
    

    (meaning all three of these things are basically the same thing)

    The differences are:

    • procs don’t throw errors for missing arguments
    • procs return from the current context
    # Should work
    my_lambda = -> { return 1 }
    puts "Lambda result: #{my_lambda.call}"
    
    # Should raise exception
    my_proc = Proc.new { return 1 }
    puts "Proc result: #{my_proc.call}"
    

    If the proc was inside a method, then calling return would be equivalent to returning from that method. — RubyGuides

    React Components

    Mapping Components

    A Component can render an Array of other Components.

    // jokesData is an Array of Hashes
    function App() {
      const jokeComponents = jokesData.map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />) 
        return (
          <div>
            {jokeComponents}            
          </div>
        )
    }
    

    Class Based Compenents

    Using ES6 classes.

    // functional Component
    function App() {
      return (
        <div>
          <h1>Code goes here</h1>
        </div>
      )
    }
    
    // class based Component
    class App extends React.Component {
      render() {
        <div>
          <h1>Code goes here</h1>
        </div>
      }
    }
    

    Any sort of logic like calculating time of date or formating data can go inside the render method or in a class method.

    // ...
    yourMethodHere() {
    
    }
    
    render() {
      const style = this.yourMethodHere()
    // ...
    

    When using props in the render method, we need to use this.props.