Code Talk - Networking

Low level talk about how information moves across the internet.

Why? Because we’re moving to AWS and Scot wants to try teaching this.

Types of addresses:

IP address Mac address
Dynamic Static
Related to geolocation (network location associated with physical location) Hardwired to computer’s network card
Higher level (IP layer, layer 3) Lower level (ethernet, layer 2)
32bit, example: 10.10.2.2 48bit, usually represented in hex, example: F1:4F:AF:FF:FF:FF

ifconfig - shows IP address, netmask, and more

$ ifconfig lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP> inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=201<PERFORMNUD,DAD> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 stf0: flags=0<> mtu 1280 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether a4:5e:60:d0:47:85 inet6 fe80::4b4:2f9:9d8c:bc76%en0 prefixlen 64 secured scopeid 0x4 inet 10.9.97.112 netmask 0xfffff800 broadcast 10.9.103.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active 

ipcalc <ip address> <netmask> - tells...

Read More

Code Reading - Learn ❤️ RabbitMQ - Part 1

A code reading by @joshrowley, part 1.

Concepts

Fuzzy overview of stuff we’ve heard about RabbitMQ

  • Written in Erlang
  • Queues, Exchanges, Channels, Subscriptions
  • Publishers, Consumers
  • Connections
  • Fanouts
  • Self-healing
  • Distributed

Actual overview

  • Message broker originally built by JPMorgan Chase. Built 2004, released 2007.
  • Designed as a way to solve problems with integration points between many different bank systems. Needed standardized way of sending messages between apps.
  • Goals: reliability, guaranteed message delivery between apps, uptime
  • Solution: AMQP (protocol)

What is AMQP?

  • Runs on Erlang OTP
  • Queues where you persist messages
  • Consumers who consume messages
  • Acks inform queue when message is processed
  • Whole thing ensures streams of data are processed as intended
  • Any client can use AMQP, so why roll your own?
  • Decouples publishers from consumers
Producer - app that publishes messages (Ironbroker, Ironboard, Flatchat) | | - TCP Connection (ongoing 2-way connection) V Broker (RabbitMQ) - Queues ("mailboxes"): hold messages, wait for consumer to connect and take message off queue, load balances - Exchanges: publishers publish message to exchange, exchange routes to queue(s) - Bindings: rules you define for how exchanges publish messages to queues - Connections:...
      
Read More

Code Reading - Learn ❤️ Domain Driven Design

Introducing DDD into Existing Codebase

Risky to experiment with existing “domains”. Better to experiment with something new.

Our test case: “Compliance” and “Notifications” domains

  • small
  • isolated
  • wouldn’t affect existing code

Test Case

Didn’t add any new has_many or other associations

Domains

Communicate with domain through top level domains/:domain modules (ex. domains/compliance.rb).

Gives us bounded context. Send messages to bounded contexts, not the subdomains directly. All requests should be funneled through top level module.

That said, we’re not being strict about this convention. You still can call models directly. We may change this in the future to be stricter, but we’re trusting our team to self police for now.

# domains/compliance.rb module Compliance def self.get_requirements_with_document(requirement_ids) Requirement.includes(:document).find(requirement_ids) end def self.requirement_complete?(requirement_id) Requirement.complete.where(id: requirement_id).exists? end # etc... end # models/requirement.rb module Compliance class Requirement < ActiveRecord::Base end end 

Fun...

Read More

How My Bash Color Settings Broke edeliver

Yep, you read that right. My bash color settings broke edeliver, the tool my team uses to deploy our Elixir apps.

Now, anyone who’s tinkered with their .bash_profile knows there’s an infinite number of ways to totally bork your system. But this bug was well camouflaged, hiding inside a common, seemingly-benign bash setting I’d had in place for over two and a half years without issue - a bash setting you, too, might have on your machine RIGHT NOW 😱

But don’t worry, I tracked down the little bugger, so read on to save yourself the same hassle I went through. And for those of you in a rush, here’s the tl;dr.

The Problem

I’d just started working on one of our Elixir projects, doing my best to learn a new codebase and a new language all at once. Things were going well until it came time to deploy changes. I could build a release, no problem, but I couldn’t deploy; the command would fail every time with the following output:

Read More

How to Run Ecto Migrations on Production

You’d think the answer to this question would be a simple Google search away. Unfortunately, that wasn’t the case for me this afternoon, working on a Phoenix project with a newly-added Ecto backend. In an effort to save others (and let’s be honest, future me) the same frustration, here’s the most straight-forward solutions I found.

What Doesn’t Work

Mix. Mix tasks aren’t compiled into your deployed release, and as evidenced in this exciting discussion, there’s no plans to change this any time soon.

So don’t try using your trusty local mix ecto.migrate task on production. Not gonna help you here.

What Does Work

1. Ecto.Migrator

Ecto ships with Ecto.Migrator, a first-class module for Ecto’s migration API.

Run it manually by ssh’ing onto your app server, attaching to your Phoenix app, and running the following:

path = Application.app_dir(:my_app, "priv/repo/migrations") Ecto.Migrator.run(MyApp.Repo, path, :up, all: true) 

Ideally, you’d wrap up the above in its own task that can be called during your build and deployment process. Check out Plataformatec’s blog for a nice example.

2. eDeliver

Our app uses edeliver for deployments, and it has...

Read More

How to Work with Developers

Presented to Venture for America 2017 Fellows

Slide deck

Text (no video available, unfortunately)

Today, I’ll be sharing my (completely unbiased) perspective on how to work with developers. My goal for this talk is for everyone to walk out today confident they can work effectively with their development team, thanks to some tools and strategies we’ll review together.

Developers: They’re Just Like Us… or are they?

So why is this talk necessary? Are developers really so different from your average co-worker?

Yes. Yes, we absolutely are.

Take Flatiron School’s engineering team, for example. Here’s a picture of us from last summer, happily hacking away in the park outside our office. Why are we in a park? Well, this was moments after our building was evacuated during a fire at about 5:30pm in the afternoon. When the alarms went off, the rest of the office did what you’d expect: went home for the day.

Not us. Without any pre-planning or conversation, every single one of our engineers picked up their laptops, filed outside, sat down on the nearest benches, and immediately went back to work. Like I said, we’re...

Read More

Code Reading - Learn ❤️ GraphQL

What is GraphQL?

  • “Graph Query Language”
  • Alternative to REST pattern
  • Making your data queryable through a single endpoint

Why use GraphQL?

  • More declarative
  • More consumer focused
  • Simplified endpoints
  • Fewer requests
    • With REST, request count grows w/ more data you need
    • With GraphQL, only request as much data as you need => more efficient

In use in the wild

  • Github API
  • Shopify

Stuff to Think About

  • Due to HTML limitations, super long queries get sent via POST request
  • Mutations

Demo

  1. Spin up new rails app: rails new graphql-demo
  2. Add graphql-ruby gem to Gemfile
  3. Run rails generate graphql:install
    • gives you graphql directory with sub-directories for mutations, types, new controller, new route graphql-rails
  4. Lookit /grpahiql loader dev tool
  5. Lookit /app/graphql/graphql_demo_schema.rb
  6. Lots of demo boilerplate-y examples generated for us
  7. Add more field queries to Types::QueryType
 field :course, Types::CourseType do description "This will return a single course" argument :id, !types.Int 

      Read More
    

Code Reading - Learn ❤️ Docker

Prereqs:

  • Watch this Youtube playlist (~90 min)
  • Clone down existing Rails app (in our case, the Learn codebase)
  • Set up account on Docker Hub

Intro

What is Docker?

  • Tool for managing and creating containers

Why use Docker?

  • Maintain a stable, consistent environment
  • Encapsulate all pices of an app
  • Uniformity and consistency
  • Step towards better deployments and auto-scaling infrastructure (Swarm, Kubernetes)
  • Lighter than a VM (no hypervisor)
  • One of the more mature tools available

Basics

Docker image:

  • Pre-packaged layer
  • Can stack layers on each other
  • Result of running Dockerfile
  • Can create containers off of image

Docker container:

  • Running isolated container of your app’s code

Docker networking:

  • Built-in
  • Allows containers to talk to each other over same network

Docker volumes:

  • Take local files and put them into your container
  • Edit locally, see changes in container

Docker compose:

  • Toolset for coordinating containers

Docker Hub:

  • Store and access repositories (images)

Practice

Run an image: docker run -it ubuntu (creates container with interactive terminal)

Build Dockerfile: docker build -t wget...

Read More

Code Reading - Capistrano

A fascinating glimpse into Spencer’s server config process.

Impetus:

Contractor working on our marketing website CMS needs a staging environment to deploy changes to.

Context:

We set up a one-click droplet on Digital Ocean. But we use chef for server management, so we need to custom configure this setup.

Requirements:

  • Wordpress
  • MySQL
  • Varnish (service that sits in front of web applications like Wordpress, handles caching, kinda like nginx with caching)

What we did:

First step was looking at our existing chef cookbooks and seeing if there’s anything we can reuse. Turns out we have fis-msql cookbook already - but why? We don’t use MySQL on production. So look for a corresponding droplet on Digital Ocean; can’t find one.

Git blamed cookbook, and it was added in March around the same time this marketing site CMS project was originally kicked off (later put on paused, restarted now).

Side note: Spencer is using the Elflord color scheme for VIM. Loves it.

Diving into fis-msql cookbook code:

  • see our base cookbook
  • setting up msql v5.6, so update to latest v5.7 (bc why not)
  • rm mysql2_chef_gem (don’t need it)
  • rm Read More

Dev Ops Crash Course - Day Five

Notes from day one, day two, day three and day four.

Chef Chat

What is Chef?

  • Scripts written in Ruby to provision a server.
  • Server setup
  • Infrastructure automation
  • Server configuration management

What’s important to manage?

  • Software versioning
  • Uniformity and consistency across machines
  • Reproducability
  • Idempotency

What problems are we solving?

  • Efficient setup
  • Preserves history
  • Prevents environment issues resulting from inconsistencies among envs

Alternatives to Chef?

How We’ve Structured Our Cookbooks

Rely on inheritance. All cookbooks include base cookbook, which makes sure we always have security standards, base stuff in place on all boxes.

Wrapper cookbooks let us have a general template we can extend with app-specific details.

Idiosyncracies of Chef

Conventions aren’t very clearly defined. Easy to define attributes all over the place (ex. in your recipes, in attributes directory, etc.)

Cookbooks have many recipes, but in our chef repo, we tend to only have one recipe per cookbook (the default recipe).

Community cookbooks

When using community cookbooks, probably want to wrap rather than fork. After a certain amount...

Read More

Dev Ops Crash Course - Day Four

Notes from day one, day two and day three.

Learn IDE

Load Balancers

Using haproxy for load balancers. Config lives in /usr/local/etc/haproxy

IDE config is using slightly different approach than Learn. Not using cookie. Instead using hashed token from user (as url param).

DNS

In general, SSL certificate needs to match what IP address the web request resolves to (resolves to DNS entry). DNS entry is for floating IP. So you can use the same certificate for multiple servers, depending on what server floating IP points to. That allows us to SSL terminate at load balancer server. Certicate is on load balancer.

We have load balancers in front of each region AND a super load balancer to handle delegation. Has 3 different A records, one per load balancer.

We’re using traffic management service on Dynect. This service allows you to set address pools and service controls.

Address Pools

Pools are preset by Dynect. We plugged in our servers where it made sense.

Global pool has all 3 main regional load balancers. Monitor and obey are active.

Serve mode off for US Central, so people get routed to closest region.

Regional rules

...
Read More

Dev Ops Crash Course - Day Three

Notes from day one, day two, and day four.

Year in Review Review (continued)

Notifications

Nagios repo w/ full documentation: https://github.com/flatiron-labs/nagios

Nagios API that powers our Learn.co status page: https://github.com/zorkian/nagios-api

Status page lives on nagios01 server: root@nagios01:/usr/local/nagios/nagios-api. There’s a cron job that runs updates: crontab -l to view, crontab -e to edit.

Automated SSH Key Propagation

Cron job that runs every 30min that runs chef user_setup recipe on every host.

Every 30min too often? We should scale this back.

Automated Server Provisioning Tools

Script that uses Digital Ocean, Dynect, and Chef APIs to provision the host automatically. New host in under 2 min.

Note: script is a little dated now. DO has since made its own CLI tools that do a lot of this (doctl). There’s also tugboat gem.

DO tools probably better suited since they incorporate all DO’s latest features.

Faster Deploys

Drew and Devin put work in to speed up server-side only deploys. More work needs to done on speeding up asset compilation.

Weekly DB Migrations

See qa-support server. Runs cron job: root@qa-support /etc/cron.d. Why Read More

Dev Ops Crash Course - Day Two

Notes from day one, day three, and day four.

Year In Review Review

Q: What is DevOps?

A: When first created, more of a concept than a well-defined position. Even today, the term is still fairly broad, but in general refers to:

..a set of practices emphasizing the collaboration & communication of both software developers and operations professionals, while automating the process of software delivery and infrastructure changes.

Postgres Database Replication

  • Read-Only replica: all transactions are mirrored to 2nd server
  • Hot standby in case of failure
  • Easy failover strategy
  • Lowers risk of downtime

Backups stored in /var/lib/postgres along with backup config.

How restore works:

  • WAL-E (continuous archiving) takes base image of our database once a day and stores in S3.
  • Postgres creates binary transaction logs (write-ahead logs) that have to complete before transaction succeeds. That way, can re-run if database crashes before completing transaction. Over the course of the day, we send up these write-ahead log files to S3.
  • For restore, first imports base image to db, then applies deltas (write-ahead logs).
  • WAL-E has interface for deleting backups. We go in every...
Read More

Dev Ops Crash Course - Day One

Notes from day two, day three, and day four.

Internet 101

Videos: https://www.khanacademy.org/computing/computer-science/internet-intro/internet-works-intro/v/the-internet-wires-cables-and-wifi

Some vocab:

  • Bandwidth: capacity to receive information
  • Bitrate: speed of sending information (bits per second)
  • Latency: drag / delay when sending information

Internet is a design philosophy expressed through agreed upon protocols:

  • IPv4 - current protocol (32bit)
  • IPv6 - new protocol to provide more IP addresses (128bit)

IP addresses have A, B, and C classes.

DNS

How DNS works: https://howdns.works/

In local network settings, DNS is set to Google Public DNS.

  • better performance
  • better security

Anatomy of a URL: https://doepud.co.uk/blog/anatomy-of-a-url

protocol subdomain domain
https:// www. google.com

DNS records

Record types:

  1. A record: address, maps hostname to physical IP address
  2. PTR record: pointer, maps IP to name (helpful when scanning logs)
  3. CNAME record: alias, map domain name to another domain name

Can use multiple records for redundancy strategy. For example, you want multiple MX records for mail servers. Config priority on each record.

DNS lookup

$ dig learn.co ; <<>> DiG 9.8.3-P1 <<>> learn.co ;; global options: +cmd ;;...
      
Read More

How Object-Oriented Design Saved Our CSS (and Site Performance)

Back in January 2016, our CSS was easily the messiest part of the Learn.co codebase… something that probably sounds familiar to many other web developers out there. Last spring, we budgeted time and resources to overhaul it. I led that project. Here’s what we learned.

Before diving in, let’s clarify what we’re talking about when we talk about object-oriented design. Object-oriented code is:

  • Modular: reusable
  • Encapsulated: self-contained with minimal dependencies
  • Maintainable: easy to work with, which is especially important for smaller dev teams like ours

Learn.co is built on a Rails backend, and Rails strongly encourages writing code in an object-oriented paradigm. But how does that apply to stylesheets? As good Rubyists, we tried to follow object orientation with our CSS, but we were doing it wrong. To illustrate, let’s take a look at our old stylesheets directory tree.

Stylesheet Directory Tree

Very similar to the Rails boilerplate setup, we had one stylesheet per view, with styles namespaced under a top level ID. This approach is fine when you’re starting out, but over time, it can get out of hand. Just look at where ours was pre-rewrite:

Stylesheet...
      </div>

      <a href=Read More

Code Reading - Learn.co Shared React Form Library

Presenter: Seiji

Problem

React is not an opionated library

  • too many options for building forms
  • we ended up with a bunch of different implementations / approaches

Forms are omnipresent in our app

  • lots of repeated code
  • need to DRY this up

Solution

  • Build out library to manage form state + validation + submission
  • Build reusable form component specific to our domain

Process

  • Reviewed all our current approaches
  • Melded into single, shareable component

Shared Component Library

Can be used for controlled + uncontrolled inputs

  • examples at /admin/react/forms
  • documentation on ironboard wiki

Robust test coverage

Default styles can be overridden

Acts as building block / starting point for new form

  • won’t just magically build your entire form for you
  • use lego blocks to build lego set

Alt Form: existing library, but outdated and not super functional, so Seiji rebuilt one specific to our app

Uses Curring pattern

  • Referred to in React community as “high order component”

3 Objects:

  1. Form Object
  2. Form Component
  3. Form Connector
Form Object Form Component \ / \ / Form Connector || \/ React...
      
Read More

React and Redux Crash Course with Steven Nunez PART DEUX

Instructor

Steven Nunez, Lead Instructor/Developer at Flatiron School

Goals:

  1. Build on what we learned last week
  2. Set up some tests

Exercise: Hacking on Our Chat App

Last time: closed out talking about Middleware (Thunk, specifically). Today we’ll make some more progress towards a nice lil chat app.

We’ll start out with by building some functional components.

  1. create new files:
    • ./components/app
    • ./components/RoomList
    • ./components/RoomDetails
  2. render RoomList and RoomDetails from App
  3. render an unordered list of Rooms (aka channels) in RoomList
  4. RoomDetails will render an individual room:
    • messages back and forth from each room member
    • also the textarea input where you can compose new messages
  5. Add some styling (lil flexbox, lil custom fonts, etc.)

Next up, set groundwork for testing. Use this post for reference: https://keita.blog/2016/02/08/javascript-unit-tests-in-a-phoenix-application/

  1. npm install --save-dev mocha
  2. npm install --save-dev chai
  3. npm install --save-dev babel-register
  4. in .babelrc, set preset: { "presets": ["es2015"] }
  5. in package.json, update scripts: "scripts": {"test": "mocha --compilers js:babel-register test/js/**/*.js"}
  6. mkdir -p test/js/reducers
  7. touch test/js/reducers/RoomReducerSpec.js
  8. write some tests (see example repo)

Let’s pause and talk about immutability.

Redux is trying...

Read More

React and Redux Crash Course with Steven Nunez

Instructor

Steven Nunez, Lead Instructor/Developer at Flatiron School

Goals:

  1. Learn through doing
  2. Knowledge up on cool new tech

Why Redux?

  1. “Surprisingly simple” says Steven
  2. Very specific purpose
  3. Supes popular
  4. Lots of high quality curriculum available from Flatiron School
  5. They hired Dan Abramov

What is Redux?

  1. State Management

The end.

  • Has nothing to do with the web.
  • Has nothing to do with React.
  • Nice and simple.

Is it Flux?

Not really. Flux has a very specific set of parts: dispatcher, actions sent by dispatcher, etc. Redux has a lot of the same players, but follows slightly different pattern.

Why Redux was hard for Steven

Seems like a lot of stuff at first.

The part that’s Redux is actually fairly small. Redux covers Reducers, Dispatch, middleware. The rest is mostly Redux+React. And then conventions like ALL_THE_CAPS and Action Creators are separate conventions (oof).

Exercise: Simple Chat App

Building a chat app

code lives at: https://github.com/StevenNunez/redux_chat_hedgehog

  1. brew install elixir
  2. mix phoenix.new redux_chat_hedgehog (using phoenix bc it has nice tools for modern web workflow)
  3. comment out db username and password in Read More

CSMess to OOCSS - Refactoring CSS With Object Oriented Design

Presented at Fullstack Toronto Conf. 2016

Slide deck

Text (no video available, unfortunately)

Back in January 2016, our CSS was easily the messiest part of the Learn.co codebase… something that probably sounds familiar to many other web developers out there. Last spring, we budgeted time and resources to overhaul it. I led that project. Here’s what we learned.

Before diving in, let’s clarify what we’re talking about when we talk about object-oriented design. Object-oriented code is:

  • Modular: reusable
  • Encapsulated: self-contained with minimal dependencies
  • Maintainable: easy to work with, which is especially important for smaller dev teams like ours

Learn.co is built on a Rails backend, and Rails strongly encourages writing code in an object-oriented paradigm. But how does object orientation apply to stylesheets? As good Rubyists, we tried to follow object orientation with our CSS, but we were doing it wrong. To illustrate, let’s take a look at our old stylesheets directory tree.

Stylesheet Directory Tree

Very similar to the Rails boilerplate setup, we had one stylesheet per view, with styles namespaced under a top level ID. This approach...

Read More

Flatchat Code Talk

Flatchat is our in-house replacement for Slack, which we’ll be moving our users off soon.

Stats

  • maxing out at ~350-500 unique websockets
  • avg 200ms room load time

Check /pghero for db query diagnostics.

ssh into flatchat server for PM2 monitoring.

  • logs are rolled over every 7 days
  • pm2 monit for live resource usage
  • pm2 list for quick summary

Handling Message

  1. Validate inputs (flatchatter and room member)
  2. Check room policy
  3. Write message to db
  4. Add more stuff to message object (decorator?)
  5. Broadcast msg
    • to other users in room
    • to other rooms
  6. Send msg info to rabbitmq for processing

Details:

  • Room stored in session
  • User bounced if no access to room / no room
Read More

Get Fuzzy with LEVENSHTEIN

Discovered a super handy Postgres extension tonight: fuzzystrmatch. This lil cutie is a real godsend when dealing with potentially crummy user input, such as, oh say, for a Rails project where you’re requiring your less-than-tech-savvy relatives and future inlaws to input their email address in order to access your wedding website. Note: said website is badass, built-from-scratch, and open source.

Here’s a visual:

Login Modal

Imagining that scenario, one might be concerned about poor conversion due to typos, misspellings, or any other of the myriad problems that plague “uncontrolled” user input. And extra sadly, poor conversion here translates to a sparsely attended wedding and future full of angry inlaws… no bueno.

Enter fuzzystrmatch. Adding this extension to your Postgres database gives you some super handy fuzzy string matching functions, my favorite of which so far is levenshtein. levenshtein calculates the difference between two strings, aka the “edit distance”, and it’s based on this metric named after this guy.

You can use it to make some extra forgiving ActiveRecord queries, as laid out below.

> User.find_by('levenshtein(lower(email), lower(?)) <= 3', 'test@email.c') => #<User id: 1,...
      
Read More

BASH Tips and Tricks

All tips courtesy @devinburnette

Basics

$ w

see who else is on box

$ w 14:15 up 5 days, 19:23, 7 users, load averages: 1.47 1.56 1.82 USER TTY FROM LOGIN@ IDLE WHAT ktravers console - Mon11 3days - _mbsetupuser console - Mon11 3days - ktravers s000 - Mon11 1:35 gulp ktravers s001 - Mon11 - w ktravers s002 - Mon11 4:10 node /Users/ktravers/.nvm/versions/node/v6.2.2/bin/sails lift ktravers s004 - Mon11 3days /usr/local/Cellar/rabbitmq/3.5.1/erts-6.1/bin/../../erts-6.1/bin/beam.smp -W w -K true -A30 ktravers s005 - Mon11 3days redis-server *:6379 

$ write [user]

send message to specific user

$ wall

broadcast to all users on box

$ whoami

get your current user

$ whoami ktravers 

$ who am i

verbose get current user

$ who am i ktravers ttys001 Aug 29 11:06 

$ clear

put command line at top of window

$ man [whatevs]

get manual for [whatevs] command

$ man man man(1) man(1) NAME man - format and...
      
Read More

React Code Talk Notes

Overview

  • library that renders data to the DOM
  • can add Flux architecture after you’re comfortable with React

Setting up a React app in our codebase

General Notes

  • avoid using jQuery so we can remove that dependency
  • use vanilla JS where possible instead
  • Gulpfile is not watching these files, so will need to re-compile manually after making changes

Setup

1. Add _src file (_src/code-reading.js)
// _src/code-reading.js var React = require('react') , ReactDom = require('react-dom') , AppComponent = require('code-reading/app.jsx') ; document.addEventListener('DOMContentLoaded', function () { ReactDom.render(<AppComponent/>, document.getElementById('js-main')); }); 
2. Create manifest (javascripts/code-reading.js) and require src file in via sprockets
// javascripts/code-reading.js //= require _bundles/code-reading 
3. Add to asset pipeline (application.rb) and blacklist
4. Create AppComponent (/javascripts/code-reading/app.jsx)
  • React.createClass(){} requires render function
  • React can only return one...
Read More

Best Ways for Beginners To Contribute to Open Source

When I first started out learning to code, the idea of contributing to an open source project was really intimidating. I got that advice from everyone - “Contribute to open source! It’s so easy! Employers love it!” - but I was still hesistant. I’d only been writing Ruby for a couple months; how was I going to contribute anything useful to someone else’s project?

Well, I’m happy to report from the other side, it’s actually pretty painless and fun for beginners at any level to make meaningful contributions to open source projects.

So shake off that imposter syndrome; the open source community needs you. They need everyone, in fact. Open source projects depend on a large and diverse community of contributors to really robustify their codebase. That includes people from all skill levels and all areas of expertise. Plus, the benefits are reciprocal. You’ll get to know the community better, build your support system, and get your name (and your code) out there in a really positive way.

Getting started

So where do you smart? The two best pieces of advice I got in this department were to 1) start small and 2) (in the immortal words of...

Read More

Code Talk Notes - Javascript Testing and Analytics

Javascript Test Updates

jsdom: npm module

  • load into node environment
  • recreate DOM
  • run inside of node using Jasmine

Jade templating

  • require in templates
  • doesn’t need to rely on Rails asset pipeline

Spies:

  • PushStreamSpy
  • spyOnBackboneHistory
  • can have it substitute the function, wrap the function then delegate to function
  • Note: mocks, spies & stubs are all very similar (functionally, conceptually)

Can write specs for Marionette views, Backbone models

  • run in node (npm t)
  • load in view (same as front end)
  • stub out fixtures
  • create view then test view

** eval(locus) == binding.pry for node **

Analytics

Tracking should be done client-side; inconsistent if tracked from backend

  • in our system, controller will delegate to client-side
  • concept of current_visitor bc we don’t have a user yet

To have access to Segment system, be sure to include analytics script call (helper method)

Use aliasing to transfer data from before user is logged in to when after user has logged in

  • data stays attached to same user
  • alias vister::user

Sequence:

  1. alias
  2. identify (updated from current visitor traits)
  3. track

Stats on Mixpanel

  • can create/view funnels
  • see...
Read More

Code Talk Notes - Librato and Ironbroker

Librato Update

Librato has two stats types: counter vs gauge

When using counter (aka #send_increment), be sure to set summary function to sum and check Service-Side Aggregation.

Librato counter

Ironbroker Refactor

Payload == immutable
State == mutable

Validation for each source

RabbitMq handler - rescue channel failure by creating new channel

begin
  # do bunny stuff
  # if channel closes, rescue
rescue
  @channel = @bunny.create_channel
  # bunny keeps hopping
end

Oj: much more efficient JSON parser

Checkout Source model for some cool meta-programming

New Hierarchy Builder

Structure determined by depth level

Query uses Postgres’s WITH RECURSIVE method

  • give it an initial SELECT statement which is run once
  • give it another SELECT statment that it calls recursively until it runs out of results
  • then combines the SELECT statement

Holds a path array while building, so you can see how you got to your final result

Test failures were a nightmare, but solved by creating a rollout_helper support method.

Read More

Code Talk Notes - Promises and Asynchronous Code

Callback Hell

Promises are a pattern for managing async callbacks.

Calling then() generates another promise object, when then resolves at the end of the chain. When promise object resolves, it resolves with the data coming back, which can then be passed to the next promise in the chain. Helps maintain the idea of a return value to asynchronous code - brings return values back.

jQuery

jQuery has promises built in, but not fully up to true A+ promise spec.

When.js

When.js is a much more robust promises library.

When.js library provides many additional helper methods for promises. You can call return when.promise(function(resolve, reject){...}) to return a promise object and pass resolve and reject functions into the promise chain.

Use tap() to add in something asynchronously to the chain.
Use catch() at the bottom of the chain to handle an error at any point in the chain.
Use delay() to add in a delay at any point.
Use timeout() to throw an error if promise isn’t resolved after a certain amount of time. Use with() to pass in a context (usually Read More

Sublime Text Key Bindings

Keyboard shortcuts are a programmer’s best friend, and Sublime Text lets you write your own. I use these five below on a daily basis, and you’re going to want to, too. Here’s the setup:

  1. Open Sublime Text
  2. Type command + shift + p to open your Command Pallette (aka super+shift+p in Sublime lingo)
  3. Select Preferences: Key Bindings - User
  4. Insert the following into this file:
[ { "keys": ["super+shift+w"], "command": "close_all"}, { "keys": ["ctrl+alt+shift+down"], "command": "goto_definition" }, { "keys": ["alt+c"], "command": "insert_snippet", "args": { "contents": "console.log(${1:}$SELECTION);${0}" } }, { "keys": ["alt+d"], "command": "insert_snippet", "args": { "contents": "debugger;" } }, { "keys": ["alt+b"], "command": "insert_snippet", "args": { "contents": "binding.pry" } } ] 

Quick summary of each key binding:

super+shift+w => close_all

Closes all open tabs.


ctrl+alt+shift+down => goto_definition

Navigates to selected method or class definition (based on your cursor’s position).


alt+c => insert_snippet ‘console.log();’

Inserts console.log(); at your current cursor position.


alt+d => insert_snippet ‘debugger;’

Inserts debugger; at your current cursor position.


alt+b => insert_snippet ‘binding.pry’

Inserts binding.pry at your current cursor...

Read More

POODR Recap, or How I Learned To Stop Injecting Dependencies and Love OO

I’ll keep this concise, in the spirit of less is more.

Reading POODR has been one of the most beneficial things I’ve done in my long, illustrious career as a programmer (clocking in at approx $("Feb 02 2015").timeago();). It’s been recommended to me since ~week 2 of my immersive program at Flatiron School, but I’m glad I put it off until I’d built some un-POODR-like apps of my own. That context helped me draw connections between the abstract principles discussed in the book and very real production code I’m working on now. So without further ado:

Main takeaways from POODR:

1. Think about code in terms of objects and messages, not procedures

As Chapter 2 emphasizes, classes (and methods, really) should have a single responsibility. If you find your class carrying multiple responsibilities, break each one into its own separate class. You should conceptualize a class as an object that passes and receives messages, not something that executes some long procedure. Objects that execute a procedure can find themselves performing multiple responsibilities.

One strong example of this is a Ruby Code Challenge feature I’m currently working on, conveniently written entirely in Javascript. Its basic functionality...

Read More

Monkey Patching truncate_html

The truncate_html gem is a really useful tool for clipping off a string of html at a designated point. It has some nice customizeable config options, and best of all, zero third party dependencies. Per its docs, it even does the unthinkable:

This library…parses HTML using regular expressions.

Today I discovered I could extend its usefulness even further with a small monkey patch. Now, before the haters come out in full force, YES - I understand that monkey patching is dangerous and needs to be handled with deft and delicacy. That said, the small size and limited dependencies of this gem make it a prime candidate for practicing safe patching, Justin-Weiss style.

Moving right along…

Desired functionality:

1. Multiple break tokens

Per truncate_html’s docs, you can truncate your html after a after a certain number of characters (options[:length]) or at a designated piece of content, like <!-- break --> (options[:break_token]).

Setting a single break_token is great if I’ve created the HTML and set my own unique break_token wherever necessary. But what about situations where I want to pass in any old HTML and...

Read More

AcademyAwardable Polymorphic Associations

If you ever find yourself in a Rails-situation where you need one model to belong to multiple other models, consider using an ActiveRecord polymorphic association. Don’t let the multisyllabic name fool you; polymorphic associations aren’t as complex to build as they might seem. You can do it.

Meryl Streep Can Do It

Let’s consider a completely relatable and engaging example: The Academy Awards. Maybe you’re building an Oscar ballot app for a family member who’s particularly obsessed with this time-honored, hallowed awards show. Your app at minimum would need to contain Actor, Movie, Director, and Vote models (plus all those technical award categories, but we’re going to ignore them for now - just like the Academy). We’ll need some savvy schema design to keep things simple and DRY.

Let’s start by trying to set up our schema the old-fashioned, non-polymorphic way first. Actor, Movie, and Director would all have_many Votes, which means Vote would belong_to Actor, Movie, and Director. Here’s how that would look in our CreateVotes migration:

class CreateVotes < ActiveRecord::Migration def...
      
Read More

It's `document.write(new Date().getFullYear());` - Update Your Footer

As I was updating some content on my personal website today, I noticed the copyright date in the footer still read “2014”. Yeah, it’s May. Go me.

Sadly, I believe future-me from 2016 would probably make this same mistake, so to help myself out, I did a quick google search for “How to auto update year website”, which yielded this extremely helpful site: UpdateYourFooter.com. It offers Javascript and PHP solutions, with JS being the easier option for my needs.

Just add the following wherever you want the year displayed:

<script>
  document.write(new Date().getFullYear());
</script>

You can find more info on the Javascript Date object here. And best of all, this solution is supported in all browsers except IE8. Finally, there’s (of course) a longer discussion about this on StackOverflow, for anyone who wants some additional reading.

Read More

Rendering from a Model with ActionView::Base.new => WAT?

I’m a firm believer in the “make it work” philosophy - solve problems first, then refactor. That said, my team may have gotten a little too creative making our last project work. Just take a look at this gnarly method we cooked up:

class Recipe < ActiveRecord::Base def recipe_card ActionView::Base.new( Rails.configuration.paths['app/views'] ).render( partial: 'menus/recipe', format: :txt, locals: { recipe: self } ) ###🙊🚷 W A T ☠😿### end end 

Yep. We instantiated a new instance of ActionView::Base in a model. And used it to render a view outside a controller. WAT?!

Before I go any further, let’s take care of the necessaries:

  • Yes, we know what we did was wrong.
  • Yes, we are deeply sorry for our crimes against MVC.
  • Yes, we’ll refactor and never repeat this grievous offense again.

But the thing is, it worked. And I’d like to explore how and why before purging this from our git history moving...

Read More

Dynamic Duos - Dependent Select Menus with JQuery and Rails

The first time I tried to apply “dynamic selection” within a Rails form - where selecting an option in one select field dynamically updates the menu options in a second select field, I had a surprisingly hard time with it. I’d watched the Railscast and read multiple tutorials, but just couldn’t crack the code.

Problem was, I was trying to use a collection of model attributes in the first collection_select menu and a collection of model instances in the second menu, organized using the grouped_collection_select helper. What I learned after much trial, error and a deep dive into the documentation, was that the menu options should both be collections of model instances, where the models are associated through a join table. <– tldr: central lesson of this post.

I could have benefitted from more explicit discussion of those mechanisms, one with a slightly more complex example than countries and states. Towards that end, let’s walk through the steps I took to apply this solution in my Rails application, Parkster.

SECTIONS:

  1. Correcting the schema
  2. Updating the seeds file
  3. Adding appropriate ActiveRecord associations to models
  4. Updating the...
Read More

Sublime Linter Rubocop Reboot

This week’s Ruby Weekly had a nice post from Matt Brictson on “Setting up Sublime Text 3 for Rails Development”. It reminded me to finally install the SublimeLinter-rubocop package. This package syncs your linter up with rubocop, highlighting “bad code” as you type (according to the community Ruby Style Guide). Great addition, right?

Well, word to the wise: don’t install a new linter package a couple hours before a technical interview. I didn’t have a chance to tweak the default settings, which as you’ll see below, are a bit…aggressive.

Mark Style Outline

I knew I’d be pair-programming with my interviewer, and no way was I gonna subject her to literally ugly code. I had to scramble to find a fix, and after jumping through a couple different sections in the SublimeLinter documentation, I found the solution. Here’s the lowdown.

Turns out you have 5 different linter mark styles to choose from. The package defaults to "mark_style": "outline". That style’s a little visually overwhelming with my current color scheme, so I decided to switch to the "mark_style": "none", so marks appear in the gutter only.

The...

Read More

Remote True is Magic

I had a really fun time this weekend building a small side project with Sophie DeBenedetto, Jeremy Sklarsky, and Rachel Nackman. We learned a lot of very cool things that you can do with Rails + jQuery, but the coolest was easily remote: true. This one little option is crazy powerful. Case in point: by adding remote: true to our Search form, our searches.js file went from this:

$(function () { submitListener(); }) function submitListener () { $('#new_search').on('submit', submitSearch); } function submitSearch (e) { e.preventDefault(); var url = $(this).attr('action'); var $form = $('form#new_search'); $.ajax(url, { method: 'POST', url: url, data: $form.serialize(), dataType: 'script', complete: function(response){} 

      Read More
    

Listen Up - Tech Podcasts

Back in my former life as an art historian / art shipper, it wasn’t enough to simply know about art. You had to know about the other people who know about art - the key figures shaping the field, your peers working on the same stuff you were - that was just as critical as being able to recite off Greek column types or the core members of the Arte Povera movement (which I can still do, thanks very much, humanities degrees).

Now that I’m joining this new realm of web development, I have a whole world of new people to get to know. Honestly, it’s been one of my favorite parts so far; the Ruby world especially has so many weird,wonderful voices, it’s been a blast reading up on and listening to the amazing cast of coders behind all these concepts I’m learning about.

One invaluable resource in this process has, of course, been podcasts. I pretty much only listen to podcasts these days (mostly comedy, with a dash of NPR and PRX staples), so it seemed natural to turn there for my tech education as well. Below are some of my favorites I’ve found so far....

Read More

Who's Ahead Now?

After week one of learning Rails, I was eager to test out my new skills on a new side project. I wanted to build something fairly simple, that would utilize skills I felt comfortable with - JSON parsing, ERB, simple search and routing - while also pushing me into uncharted territory, like deploying on Heroku. I spent the afternoon brainstorming, circling around some sort of app that would answer a single simple question (like Is It Raining?, one of my fave single serving sites). I had a couple good ideas, but my partner came up with the best one: is Hillary winning?

Now obviously a website that just says “aw yass” every time it renders doesn’t have much utility. So I decided to expand the concept a bit and build a site that yields the current frontrunners for each party in the current presidential race. A quick rubygems search pointed me to HuffPost’s Pollster API, which is really nicely maintained. Armed with data and a plan, I started building.

Texts from Hillary

The app ended up being pretty simple:

  • One model (Search)
  • Three controllers (ApplicationController, SearchController, and WelcomeController,...
Read More

--no-test-framework

Note to self:

Bart Simpson chalkboard

Why? Without the --no-test-framework flag, Rails generate will do the following:

a) overwrite any existing tests that you, your colleagues, or your instructors have already written for that particular object

b) generate unnecessary / unwanted tests (see Thoughtbot’s helpful post on diminishing test coverage returns).

Better to write your own tests. Here’s hoping repetition leads to retention…

UPDATE: my classmate Rachel Nackman wrote an excellent blog post on Rails generators, which included an extremely helpful tip for not overwriting tests. Just add the following code to your config/application.rb file:

module Testing
  class Application < Rails::Application
    ...
    config.generators.test_framework false
  end
end

Voila! Your generators are now auto---no-test-frameworked.

Read More

Flatiron Twitter CLI

Last week, Avi pitched a pretty cool idea to the class: build an “auto-follow bot” for Flatiron student twitter accounts - something we could use to easily auto-follow everyone in the class.

Avi Flatiron Twitter pitch

I’d been looking for a side project to work on (inspired by my classmates who’ve built some very sweet side-projects already: ex.1, ex.2, ex.3, ex.4) and this seemed like a perfect opportunity. I’ve never built a bot, but I know how to build a CLI, so I put labwork on pause and spent my Saturday building the FLATIRON TWITTER CLI instead (available at your local github).

Let’s walk through the build, starting with setup. I tried to follow best practices, setting up bin, config, and lib folders, along with a Gemfile and README.

Right off the bat, my bin/run file almost sunk me. I wanted users to be able to initialize the CLI by simply cd’ing into the directory and running bin/run.

#!/usr/bin/env ruby require_relative '../config/environment' FlatironTwitterCLI.new.call 

I thought the code above would do it, but...

Read More

Refash Your Bash - Bash Prompt Customization

When I was just starting out learning to code, it quickly became clear I’d be spending a lot of time in Terminal. Never one to skimp on workspace feng shui - just ask my old art world colleagues - I set about post haste to fine tune the CRUD out of my bash profile, starting with the bash prompt.

Now, I’ll caution, there’s an endless plethora of resources out there on the ol’ internet about customizing your bash prompt, and my first time through, I think I read nearly all of them (really went down the .bash_profile rabbit hole, I’ll admit). To save you some time and tedium, I’ll summarize my specific mods below, with tl:dr links to resources for further customization.

Note for fellow rookies: My bash prompt is contained inside a nice little function at the top of my .bash_profile file. I’d recommend putting this function towards the top since 1) your terminal loads the prompt first and 2) that way it won’t interfere with any of the rest of your bash code below. Now without further ado …

###My Complete Bash Prompt Function

function parse_git_branch { git branch 

      Read More
    

Using Github for Lecture Notes

Flatiron School has a great system for sharing lecture notes: a dedicated Github repo. I forked the repo during week one, thinking I’d pull down the files to my local, take notes on the notes (Inception-style meta-noting), then push back up to my forked repo. No sweat.

But then comes the scary part for us git-n00bs - getting updates. I felt real comfortable pushing to / pulling from my own repositories. But to get the next days’ lecture material, I was gonna have to add my instructor’s repo as a remote. Yikes. Now that’s a scary connection to make. Any mistakes, and I’m screwing up the lecture docs for Avi, who might have to redo them, and my classmates, who need this material asap for labs + projects. I needed to handle this delicate operation with extreme care.

Indiana Jones Raiders of the Lost Ark animated gif

As I now do in all these types of situations, I went straight to Github support. Here’s the solution, specific to our Flatiron repo.

1) Open Terminal and cd to whatever folder you want to use for lecture notes storage.

...
Read More

Adventures in DNS Configuration

###Or How I Stopped Worrying, and Learned to Love GitHub Support

One of the main tenants of the The Flatiron School is “Always be a beginner,”* which has been pretty easy for me to embrace so far, since I am the noobiest of coding noobs right now. Pretty much every day, I’m reminded of my beginner-dom, even in realms I thought I’d more or less mastered.

Case in point, this very blog.

Day one, we were asked to set up technical blogs, which we’d use to write about all the cool new concepts we’re learning. I was pretty excited to dive right in, especially since I’d just built my own portfolio site at my newly-purchased custom domain, kate-travers.com. When I found out GitHub offered free hosting through GitHub pages, I about flipped. This was gonna be great. I could build out my new site with a SEO-friendly blog feature, perfect my git skillz and gain all kinds of Github coder cred in one fell swoop. I was a subdomain and CNAME record away from blogging like hacker.

Now, this was not my first time at the DNS-configuration rodeo. I’d set up probably +10...

Read More