Work Journal

This is something I'm just starting to try out (as of July, 2019). These will be shorter posts on my work-related endeavors and education. Anything from an obscure programming tip that I just discovered to a status update on a side project to an educational book I just started reading.


Running Elixir tests in VSCode

In Vim-land, I use the vim-test plugin for quickly executing tests from a command line shortcut1. I wanted to reproduce this behavior in Visual Studio Code, but I couldn’t find an extension that worked in multiple languages (namely, Ruby, Elixir, Javascript, and Elm). I’m mostly just using VSCode for Elixir, but I still liked the idea of finding a more general purpose solution.

So instead I used VSCode’s support for Tasks to build the functionality myself. So in my project’s tasks.json file, I have the following 3 tasks for running all tests, a single test (whatever is under the cursor), and the current file’s tests.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "mix test",
      "type": "shell",
      "group": "test",
      "command": "mix test",
      "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": false,
        "panel": "shared",
        "clear": true
      }
    },
    {
      "label": "single test",
      "type": "shell",
      "group": "test",
      "command": "mix test ${relativeFile}:${lineNumber}",
      "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": false,
        "panel": "shared",
        "clear": true
      },
      "runOptions": {
        "reevaluateOnRerun": false
      }
    },
    {
      "label": "test current file",
      "type": "shell",
      "group": "test",
      "command": "mix test ${relativeFile}",
      "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": false,
        "panel": "shared",
        "clear": true
      },
      "runOptions": {
        "reevaluateOnRerun": false
      }
    }
  ]
}

Next, I setup keyboard shortcuts to run these. You can access this json file by going to Preferences –> Keyboard Shortcuts, and then clicking the {} icon. I used alt-t and alt-shift-t for single test and current file, respectively. I didn’t create one for running all of the tests because I don’t do that frequently enough to warrant a shortcut.

    {
        "key": "alt+t",
        "command": "workbench.action.tasks.runTask",
        "args": "single test",
        "when": "editorLangId == elixir"
    },
    {
        "key": "alt+shift+t",
        "command": "workbench.action.tasks.runTask",
        "args": "test current file",
        "when": "editorLangId == elixir"
    },

  1. I have an article about this, but my setup has since changed to use this plugin instead. 

SSH Tunnels into Production Rails Database

Today I needed to access a production database for my Rails app directly using a GUI application on my mac, so I figured out that this can be done by creating an SSH tunnel like so:

ssh -Ng -L <local-port>:<remote-host>:<remote-port> <user>@<remote-host>
ssh -Ng -L 3307:100.64.26.11:3307 adam@100.64.26.11

And then, in your Rails app, update the database.yml as if you were connecting to a local database, but specify the proper database name.

development:
  adapter: mysql2
  database: myapp_production
  host: 127.0.0.1
  port: 3307
  username: root
  password: secret
  encoding: utf8

Rails presence method

I use Rails’ present? method constantly, but recently I stumbled across the presence method.

In the past, I have often found myself doing the following because params[:foo] could be nil or a blank string.

foo = params[:foo].present? ? params[:foo] : "something else"

I hate that i have to write params[:foo] twice. But the presence method is handy for this case. It returns nil if the item is nil or a blank string, but otherwise returns the value.

foo = params[:foo].presence || "something-else"

VSCode + ElixirLS = 👍👍

I’ve played around with VSCode here and there, but as a fairly picky Vim user who doesn’t do TypeScript, I never quite understood the hype.

Today I started up a new Elixir / Phoenix project (more on that to come) and tried out the Elixir Language Server Extension and the integration is very impression. Code completion, debugger support, automatic inference of Dialyzer Typespecs, documentation on hover, and more….

I don’t expect to be using VSCode as my standard editor (again, picky Vim user1), but I think I’ll stick with it on Elixir projects.


  1. The vim-mode extension has improved dramatically, but still not quite like the real thing  

Netlify Analytics First Impressions

My new website is hosted on Netlify, which is an awesome service for hosting static websites. Recently, they launched an Analytics Platform as an alternative to Google Analytics. My impressions of this new tool isn’t quite as enthusiastic as their service in general, but it does have some nice features.

Netlify Analytics Screenshot

Pros:

Server Side
  • Can’t be blocked by Ad-Blockers
  • Tracks requests of non-web-page assets like RSS feeds, images, etc
  • No impact on your client side performance since there’s no Javascript library
Privacy Centric
  • Isn’t connected to an ad network that’s building a database of what sites you’re browsing


Cons:

Server Side
  • You can’t track any user behavior via Javascript. I never do this anyway, but many sites do.
Extremely barebones
  • No way to filter users by geography, browser, OS, etc
  • No way to exclude people by IP address. I generally like to exclude my house and my office.
  • No way to track conversions / goals
Expensive!
  • $9/month is expensive for such a barebones feature set. Particular when compared to $0 for Google Analytics.
  • This is somewhat mitigated for me by the fact that my site falls under the free tier of their hosting service.


Conclusion:

I like the general premise of Netlify Analytics, but given the lack of features and price, I suspect that I’ll cancel it off after a month or two. But I’d wager that this is just the MVP for what will eventually become a much more comprehensive tool. So perhaps check back in a year.

TIL: Pass in an ActiveRecord Object to a where string

I’m surprised I didn’t already know this, but if you have an ActiveRecord where statement that references an id column, you can just pass in an object and it will pass in the object’s id, not the string representation of the object.

company = Company.find(1)

User.where("users.company_id = ?", company)
# is equal to
User.where("users.company_id = ?", company.id)

So when you create named scopes, you don’t have to do the song-and-dance where you check to see if the object is a model or an integer, as shown below.

scope :by_company, lambda { |company|
    company_id = company.is_a?(Company) ? company.id : company
    where( "users.company_id = ?", company_id )
  }
}
# You wouldn't actually want to use a string in this example.
# Try to only use strings in very complex scopes and queries.

Lookup IP Address & Location via the Command Line

With ifconfig.co, you can lookup your external IP Address and Location Information using a simple curl command. You can use it like so:

$ curl ifconfig.co/json
{
  "ip": "96.27.202.202",
  "ip_decimal": 1612409628,
  "country": "United States",
  "country_iso": "US",
  "city": "Columbus",
  "hostname": "d27-96-101-101.nap.wideopenwest.com"
}

$ curl ifconfig.co/city
Columbus

$ curl ifconfig.co/country
United States

Website Revamp! And introduction to my Work Journal.

My website has gone slightly stagnent lately, so I decided that it was time for a revamp. There were a few things I didn’t like about the old website:

  • As a developer with some design chops, I never liked the fact that I hadn’t designed my website myself. I was using the Hyde theme for Jekyll.
  • I felt boxed in by the fact that all my previous posts were longer-form articles.
  • While Jekyll is a great tool, it’s very blogging-centric, and I wanted to add new types of content.

So I re-designed the website from scratch using Middleman. I started with Thoughtbot’s base Middleman template, but I changed quite a bit from there. And all the design is custom. I’m pretty happy with the result. And finally, I added a “Work Journal”, where I plan to write shorter, more informal posts on what’s going on in my work. That could be something I learned, a book I just read, a status update on a side project, etc.

Exciting things to come!