Thoughts as a Developer Advocate

It has been almost a year since I graduated from DaVinci Coders, where I learned about Ruby and Rails. Since then, I have been a TA, worked as a consultant, and ultimately landed a job at TextUs. It hasn’t been easy, but it has been fun, exciting, and rewarding. Part of the reason I decided to pursue this career path was because of my brother, Nate, who encouraged me to take advantage of my technical savvy. Here are his thoughts on graduating from DevBootcamp in San Francisco, and how going to a bootcamp doesn’t necessarily mean you have to become a developer.

Nathan M Park – A Letter to bootcamp grads, 6 months as a Developer Advocate

GlueCon 2016

The past two days, I have been attending Glue Conference in Broomfield, CO. As they say, “Glue is a case study of what a conference is supposed to be.” Being a new software developer, it was the first tech conference I’ve ever attended, so I don’t have a gauge on whether or not it was better or worse than the average. That being said, I can say that I really enjoyed myself and learned A TON. Here are some of my reflections on the past 48 hours.


Pros
  1. You learn a LOT about emerging technologies and best practices for design and development. At my work, we have an API that our customers can interact with to integrate with their own software. We use Swagger to document our API, which works pretty well for our needs. One of the seminar tracks offered at GlueCon was all about APIs: design, implementation, maintenance, and deployment. What I took for granted at work was suddenly demystified; suddenly I could understand WHY our API was designed the way it is. Hearing people talk about big ideas helps you go beyond the HOW of developing.
  2. You get to have fun! I came into the conference with a very serious attitude. I told myself, I would be professional, network, and learn as much as I could. But everyone else seemed to have a different agenda. Obviously, people are there to learn and network, but they are also there to catch up with friends, make new ones, and just talk about what they’re interested in. I had a great time meeting tons of people, exchanging information, and just being able to share my excitement about being an up and coming developer. As an added bonus, you get a ton of free swag at these events – STICKERS GALORE!
  3. The keynote speakers are excellent. While some of the breakaway optional lectures were not the most exciting, all of the keynote speakers were quite good. While I wasn’t always able to follow them exactly (like the one about data encryption and authorization), I did get a sense of the scope of their ideas and the issues they were trying to address. More importantly, I learned how I fit in this grand ecosystem of development. It’s exciting when you begin to understand the role you play as a developer.
  4. You get to ask questions. Go to the booths and talk to people. Usually they want you to know all about their product, and if you don’t know what they’re talking about, they are willing to break it down and explain it to you. Before yesterday, I really had no idea what proxies were, but a gentleman at linkerd was willing to help me understand how their product fit in side-by-side with any existing app. Because there are so many people with so many specialties, you have the opportunity to be brave, ask questions, and learn so much from experts.

Cons
  1. You will feel like you know nothing. As a new developer, I was overwhelmed by the many facets of development that I still don’t understand. Most of the attendees were much older than me and had be in the tech industry for multiple decades. They would make jokes about the old days when they had to manage fires with their deployment and all I really know is how to use heroku to deploy my apps. That being said, it motivate me to work harder and try to be a more complete developer. I don’t necessarily need to be an expert in everything, but understanding my place will make me a stronger coder in the long run.
  2. Some people are not friendly. Just a couple of times, I mentioned that I was a Ruby on Rails developer and the person I was talking to straight up scoffed at me. Another time, someone tried to make a joke about how they felt sorry for my struggles. Look, I understand that maybe you don’t like Ruby or you might have opinions on my language of choice, but that doesn’t mean you have to be a dick. I found the best way to approach this behavior was to just smile, carry on, and try to leave as soon and politely as possible. I’d rather spend my time talking to people who are willing to help me grow as a coder and not just pigeon-hole me into some “this person is stupid” category.
  3. Some presentations are not good. There’s no getting around attending a few sub-par presentations. Not everyone can be a rock-star public speaker/developer/comedian/motivational speaker/coder/graphic designer. There was one talk I attended that was absolutely atrocious, and I tried my best to stay engaged and learn something. But I learned nothing because the speaker was too quiet and the content too dull. Since conferences are very long and exhausting, my advice would be to leave the room, take a walk, get some fresh air, and recharge for the next few hours.

Advice
  1. Go register for a conference! They are AWESOME.
  2. Look for scholarships online or ask your company for a subsidy. Maybe your boss is super nice and will support you if you’re going for a specific reason.
  3. Email people you want to meet before hand. Personally, I got a lot out of GlueCon specifically because I was able to meet with Lee Hinman from Elasticsearch, who gave me some great advice on implementing Elasticsearch into our Rails app at work.
  4. Go to the keynotes addresses. You may not understand everything the speakers are talking about, but you’ll definitely learn something.
  5. Take breaks. Go to the vendors and get some swag or go for a walk. It’s hard to sit through 6 straight hours of lectures.

Personally, I think GlueCon is amazing and I am definitely going to return next year. Hope to see you there!


2016-05-26 13.40.51

People start to trickle in and the exhibitors get fired up

2016-05-26 13.41.55

Joe Beda talks about authorization in the modern world

2016-05-26 13.01.31

I wont a Kindle Fire from Circonus!

How to change test environment variables

There are times when you might want to change your environment variables within a testing environment. Maybe you want to communicate with a different server or want to enable some kind of functionality that is normally disabled for testing. You can use stubbing to elegantly and temporarily just set your environment variables within a test.

ENV.stub(:[]).with('FEATURE_ENABLED').and_return('true')

Here, I am enabling a feature that allows us to access user information. Normally, the lookup is computationally expensive so we don’t run it on all of our tests. But when the need arises, it’s good to be able to change your environment variables easily within a single test.

The limits of pg_search

At work, I’ve been tinkering with Postgres and trying to optimize the search that we have implemented for our company’s app. For those of you who don’t know, Postgres comes with a lot of great built in functionality to carry out full text search on your database. In our Rails app, we use a gem called pg_search that makes use of a lot of these features to quickly and easily set up a search engine for your website. Let’s say you wanted to be able to search through a list of contacts; with pg_search, you just have to set up a simple search scope.

class Contact < ActiveRecord::Base
  pg_search_scope :search, against: [:first_name, :last_name]
end

Now we can simply call the search method on the contacts table to find records quickly and easily.

Contact.search('Tim')

We make use of pg_search’s other search function, called multisearchable. The code required to set it up is very similar to a simple pg_search_scope.

class Contact < ActiveRecord::Base
  multisearchable against: [:first_name, :last_name]
end

The difference is that multisearchable utilizes a PgSearch::Document, which is a record that points back to the original search object. So if you wanted to search across multiple tables, PgSearch::Documents allow you to query the pg_search_documents table and pull up any records belonging to a specific type. The great thing about multisearchable is that it returns ActiveRecord::Relations, which means that you can chain commands onto your search result.

PgSearch.multisearch('Tim').where(searchable_type: 'Contact')
PgSearch.multisearch('Tim').where(searchable_type: 'Contact').where(last_name: 'Park').limit(5)

You can even make use of more advanced search techniques such as employing use of dictionaries, indexes, and weighting.

PgSearch.multisearch_options = {
  using: {
    tsearch: {
      prefix: true,
      dictionary: 'english'
    }
  }
}

One of the problems we come across is that while multisearchable is convenient and fast, it takes up a lot of space. Any time you create a new record, you are also creating a PgSearch::Document to point to it. And because our PgSearch::Documents make use of a GIN-indexed tsvector column, creating and updating our pg_search_documents table is taxing on our system and an expensive use of space. Unfortunately, we can’t use the simple pg_search_scope because it doesn’t really support searches that perform table JOINs.

In an effort to try and remove the need for the pg_search_documents table, I tried to create a method that would be able to search our database without the need for pg_search and multisearchable. I began by indexing all of the tables we search with a tsvector, which simply represents documents into an easily searchable form. Thoughtbot published a great blog post detailing how to generate a migration to create an indexed tsvector on your tables. We use GIN indexing, but it’s likely that for smaller apps, a GIST index will be better. For more information, you can read the Postgres documentation about it, but here’s the main takeaways:

In choosing which index type to use, GiST or GIN, consider these performance differences:

  GIN index lookups are about three times faster than GiST

  GIN indexes take about three times longer to build than GiST

  GIN indexes are moderately slower to update than GiST indexes, but about 10 times slower if fast-update support was disabled (see Section 54.3.1 for details)

  GIN indexes are two-to-three times larger than GiST indexes

As a rule of thumb, GIN indexes are best for static data because lookups are faster. For dynamic data, GiST indexes are faster to update. Specifically, GiST indexes are very good for dynamic data and fast if the number of unique words (lexemes) is under 100,000, while GIN indexes will handle 100,000+ lexemes better but are slower to update.

Ultimately, I was able to create an ‘alt_search’ method that executed a raw SQL query to return a list of results. It’s important to note that on the contacts table, the :tsv column is a tsvector of :first_name, and :last_name and the :tsv column on the addresses table is a tsvector of :address, :city, :state and :zip_code. The problem with the SQL query is that it return a hash where each ActiveRecord::Relation is returned as a JSON object. To end up with an array of ActiveRecord::Relations, I had to do an ActiveRecord query through the contacts table once again to find our results by ID.

def self.alt_search(query)
  sql = <<-SQL_QUERY
    SELECT contacts.id
    FROM contacts
    INNER JOIN (
      SELECT contacts.id AS pg_search_id,
      (
        ts_rank(
          (contacts.tsv),
          (to_tsquery('english', '#{query}')), 0
        )
      ) AS rank
      FROM contacts
      WHERE (
        ((contacts.tsv) @@ (to_tsquery('english', '#{query}')))
      )
      ORDER BY rank DESC
      OFFSET 0
    ) pg_search ON contacts.id = pg_search.pg_search_id

    UNION

    SELECT contacts.id
    FROM contacts
    INNER JOIN (
    SELECT addresses.id AS pg_search_id,
      (
        ts_rank(
          (to_tsvector(addresses.city)),
          (to_tsquery('english', '#{query}')), 0
      )
    ) AS rank
    FROM addresses
    WHERE (
      ((addresses.tsv) @@ (to_tsquery('english', '#{query}')))
    )
    ORDER BY rank DESC
    OFFSET 0
  ) pg_search_phones ON contacts.phone_id = pg_search_phones.pg_search_id
  ;
SQL_QUERY
  @matched_contacts = []
  results = ActiveRecord::Base.connection.exec_query(sql)
  if results.present?
    results.each do |msg_hash|
      @matched_contacts << (msg_hash['id'].to_i)
    end
    Contact.where(id: @matched_contacts)
  else
    nil
  end
end

At first, this method proved to seem promising as it was almost an order of magnitude faster than multisearchable queries. However, when you start working with large tables (millions of records), pg_search shines. The power of the PgSearch::Document is that it serves as an indexed table of its own. You can query all of your tables at once and then filter through the documents. In addition, it’s obvious that implementing pg_search is much easier. Imagine trying to refactor that SQL query when your tables change or you add new model attributes!


For now, it seems as though we’ll have to live PgSearch::Documents and look for other options. Many of the most visited websites in the world make use of Apache Solr and it seems as though we may be headed that way. But if you’re in a similar situation, I recommend that you take the time to at least GIN-index your pg_search_documents table. We have found that this increases search speeds by up to 50%, which can be dramatic when you’re searching a table with millions of records.

EDIT: After some research and experimentation, we decided to use Elasticsearch. Our Elasticsearch node is hosted by Bonsai, which is an easily available add-on through the Heroku marketplace. Elasticsearch allowed us to drop our PgSearch::Documents table, which was almost 10 GB!!! I highly recommend you look into Elasticsearch if you would like to include some search capability into your app. If you’re looking for some direction, shoot me an email!

Testing to prevent normalization of deviance

In my other life, I’m an avid climber and spend a lot of my time outdoors scaling mountains over rock and ice. When I’m outside, I never take safety for granted and am constantly assessing each moment for potential risks. What happens if I fall? What if that block of ice suddenly cuts loose? It’s often easy to do because the consequences of a climbing accident are monumental – I’ve lost more than one friend from climbing.

As a result, I have certain precautions to help me prevent a fatal climbing accident. I have a checklist to make sure I bring the right gear when I go outdoors. I make sure I have a first aid kit, some rescue gear, and a competent climbing partner. When the risks are too high, I turn back and tell myself I’ll climb that mountain another day.

So why don’t I hold myself to the same standards for coding? I was watching a video about the normalization of deviance and it’s role in the Space Shuttle Challenger Disaster. If you’re unfamiliar with the concept, it explains how high-pressure situations cause you to take shortcuts. And after some dumb luck, you convince yourself that taking shortcuts doesn’t have any consequences until that one moment when your luck runs out. And then I got to thinking about how I could apply this to my daily life. With climbing, the application is obvious, but what about coding?

 

 

Recently, I’ve been messing around with small coding projects in my spare time without any real plan or goal except to learn. It’s incredibly easy to just checkout a new branch and hack away unhindered by guidelines or tests. The consequences for doing so are relatively low with coding; nobody is going to die if you don’t write tests. But ultimately, I’ve found that coding without any real plan only creates problems. If you lower your expectations and take shortcuts in order to build something quickly, bugs will inevitably plague you down the road. Experienced coders probably know this and take measures to prevent themselves from going down this path.

So today I’m going to try and make a commitment to always code with a plan. That doesn’t mean that I won’t stop tinkering with projects without tests. And it certainly won’t prevent me from making mistakes. But I think it’s good to try and remember that being a skilled coder means understanding the consequences of your actions in the future and holding yourself to the highest standards possible.

DaVinci Coders – Bootcamp Review

It’s been over a month since I’ve written my last post. And quite frankly, I regret it. The truth is that my last month has been extremely busy. I worked on a couple of projects at DaVinci Coders, had some scheduling issues at my job, and worked through some personal difficulties. But those aren’t good excuses.

Recently, I’ve been reflecting a lot on the last month where I’ve worked on two projects for DaVinci Coders. The first, Shift Scheduler, is an app that allows people to conveniently manage employees schedules. The second, Tracker Request, uses the Pivotal Tracker and GitHub APIs to create a one-stop-shop for managing projects. I want to recap the important bits from my last month at DaVinci Coders.


Test Driven Development is an invisible savior

If you’re new to TDD, I know it can be extremely overwhelming. I used Rspec and Capybara heavily at DaVinci Coders and honestly it felt like I had to learn two new languages in addition to Ruby. But after struggling with it for a long time, I started to realize the invaluable benefit of testing.

While working on Shift Scheduler, I found that having tests enabled me to work confidently because I knew my test would help me find major bugs in my code. In addition, when a problem did occur, Rspec output would point me in the right direction instead of having to trace through the MVC architecture and figure out where the problems were occurring.

One tool that I started to use often was the byebug gem. It is an amazing debugging tool that allows you to test your code at points of failure within a rails console-like terminal.


There is a gem for everything

Go to Ruby Toolbox and search for anything your heart desires. It’s amazing to see how much effort people in the Ruby community have put into creating gems to cater to your needs. I remember a distinct moment when I was pair programming with Danny and we needed to figure out a way to format some of our json output. We spent about 30 minutes reading about the topic and then found a simple gem called Active Model Serializers that allows you to easily format json in Rails.


There is no alternative to a good team

Early in our Ruby on Rails course, we learned about pair programming and it’s role in productive coding. I tried to pair with as many of my classmates as possible and I learned that there is an art to being able to work with all manners of people. Everyone works, thinks, types, and talks at a different pace and in unique ways. And I learned so much from my classmates in seeing code through their viewpoint.

Especially while we were all working with our projects, it was so obvious how productive our teams were when everyone was communicating well and being open. Progress always stalled when people were prone to ignoring Slack messages and when individual programming was favored over pair programming. To be fair, we all had our own busy lives to deal with, but I never regretted taking time out of my day to schedule a time to pair. It’s just easier to stay focused and motivated with a partner in crime.


You can do anything…

On day one of class, I was overwhelmed with our syllabus. It covered so many topics, each of which seemed to merit a class of it’s own. And if you had told me that I had to built a fully functional web app in 13 weeks, I would have bailed out of there. But it’s inspiring to see how far I, and my fellow peers, have come in 13 weeks. Some of them came in with no coding experience and helped build amazing sites like Speed Op and Footloose. It just goes to show that you can accomplish anything you want as long as you’re willing to put in LOTS and LOTS of work. Also…


…especially if you have an amazing instructor

…it helps to have an amazing instructor, like Jason Noble. He’s a top Rails contributor, his depth of knowledge seems limitless, and most importantly – he’s extremely patient. Anytime I had a question or wanted to delve deeper into a topic, Jason had an answer or could point me in the right direction. I enjoyed his teaching style as he would often hold our hands in class for difficult concepts and then let us explore other topics on our own.

If you are looking to learn more about Ruby On Rails and want some instruction, I highly recommend looking into DaVinci Coders. If you do decide to take this course, I have a few pieces of advice for you below.


How to Bootcamp

Make friends with everyone

You can learn something from everyone. My greatest ‘AHA!’ moments came while pair programming with others. Often, I would explain a concept they were struggling with and realize that I actually knew what I was talking about. Most importantly, you can always share knowledge. There is too much information covered in this course for you to become an expert at everything. Maybe you are really good at testing, but your friend is a Git master, and the quiet classmate in the corner is secretly a JavaScript guru.

Focus on one topic at a time

In the first month of class, we covered Git, the Command Line, Pair Programming, Agile Development, Ruby, and TDD. There is ABSOLUTELY no way to learn all of this at once, so pick a topic that interests you and read about it obsessively for 3-4 days. When you feel comfortable, move onto the next topic. I found that tackling concepts in a slow piecemeal way was much less overwhelming than trying to read about all topics at once.

My advice is to get really comfortable with Git first. It’s the foundation of modern version control and allows you to fix code mistakes easily. I saw some of my classmates struggle with Git and it reduced their productivity.

Ask for help

This was my greatest weakness in class. Too often, I read at length about topics like TDD and Active Record without asking the right questions to my instructor, TAs, and mentors. The great thing about DaVinci Coders is the plethora of resources available to you. But if you get too deep in the documentation or blog posts, it is easy to forget that sometimes the right question will save you hours of aimless reading.


Overall, I’m so glad that I took the Ruby On Rails course at DaVinci Coders. I learned a lot in the last 13 weeks and even though it was stressful to complete our final projects, I had so much fun doing it. I feel confident now that I was meant to become a developer and I’m excited for this new chapter in my life. The next couple of months, I’ll be searching for work and while that will be another challenge, I can’t think of anything else that would make me happier.

Test Driven Development – writing better code

Test Driven Development is a development tool used to write code quickly and efficiently. The foundation of TDD lies in following three simple steps: (1) write a failing test, (2) write the simplest code to pass the test, (3) and then refactor. The goal is to tackle large projects by breaking them into smaller tasks and working on building the code base one step at a time.

This process works extremely well once you become practiced at it. And it’s power becomes quite apparent when tackling complex projects, such as an already existing web framework like Rails. Instead of worrying about how each of the components in an MVC framework will interact, you write a series of small tests and just get them to pass. As you continue to write tests, your failure messages will provide clues for where your code has holes and how you might be able to fix them.


Law of Demeter

The Law of Demeter, also known as the Principle of Least Knowledge, is a set of rules that is often implemented in test driven development. In summary, it proposes that any given object should ‘know’ as little as possible about the overall structure of code or any of the other components with which it interacts.

For example, in Rails, the models of any application are only responsible for interacting with the database and the controller. In order to affect the views, the model must pass information through the controller. This sort of ‘middle man’ interaction is a huge advantage when you need to fix only a section of code.

By breaking up a large application into smaller interacting bits, you can easily understand how the objects interact. Therefore, when you inevitably cause changes in the program’s behavior by re-writing code, it’s easy to identify what made those changes occur. When things break, it should be easier to fix since objects are less inter-dependent to function properly.


Tools for testing

If you’re getting into Ruby and Rails, it’s highly likely that you’ll use rspec and capybara at some point during your career. Rspec is a tool that allows you to write expectations for how Ruby should function and capybara provides a way to test real world scenarios for web applications. Once you get familiar with these tools, they can be incredibly useful for writing clean, maintainable code.

Here is a real example of some code written in rspec to create a CashRegister class. Some of the code has been indented to fit better on a normal desktop screen. Note that rspec is configured in a way to make it easy to understand what we expect to code to accomplish. The keyword subject is a shortcut for an instance of the CashRegister class (subject = CashRegister.new). So in the first test block, we are describing a method called total that ‘should print a starting total of $0.00’ and then modify the total anytime the purchase or pay methods have been called.

describe CashRegister do
  describe '#total' do
    it 'should print a starting total of $0.00' do
      expect(subject.total).to eq('$0.00')
    end

    it 'should print the correct total 
        after a payment or purchase' do
      subject.purchase(4.12)
      expect(subject.total).to eq('$4.12')
      subject.pay(3)
      expect(subject.total).to eq('$1.12')
    end
  end

  describe '#purchase(amount)' do
    it 'should add a specified amount to the total' do
      subject.purchase(4.12)
      expect(subject.total).to eq('$4.12')
    end
  end

  describe '#pay(amount)' do
    before(:each) do
      subject.purchase(2.18)
    end

    context 'when the payment is less than the total owed' do
      it 'should subtract a specified amount from the total' do
        subject.pay(2)
        expect(subject.total).to eq('$0.18')
      end
      it 'should return a string that shows the remaining total' do
        expect(subject.pay(2)).to eq('You still owe $0.18.')
      end
    end

    context 'when the payment is equal to the total owed' do
      it 'should reset the total to zero' do
        subject.pay(2.18)
        expect(subject.total).to eq('$0.00')
      end
      it 'should return a string that thanks 
          you for paying the exact total' do
        expect(subject.pay(2.18)).to 
            eq('Thank you for paying the exact amount. 
                There is no change.')
      end
    end

    context 'when the payment is greater than the total owed' do
      it 'should reset the total to zero' do
        subject.pay(3)
        expect(subject.total).to eq('$0.00')
      end
      it 'should return a string that shows your change' do
        expect(subject.pay(3)).to eq('Your change is $0.82.')
      end
    end
  end
end

Feel free to take this rspec file and write some code to get all of your tests to pass. Remember, you’ll need to install the rspec gem and make sure you have all of the files set up properly. Specifically, your rspec file should use require_relative to point to the actual code you are testing. Once you’ve got everything working, try to write the test from scratch to get some practice writing tests yourself. Remember, the goal is to (1) write one test, (2) make it pass, (3) refactor and then REPEAT. Don’t try to recreate the entire test file all in one go. Good luck!