Your friends at Viget present Extend, a Code & Technology Blog

Bandwidth-Aid: A VPN disconnect reminder script

VPNs are great for allowing you to do certain things that require being on your company's network while you're on an external internet connection. At Viget, we use a VPN for a number of activities: connecting to internal servers, viewing secure internal websites, deploying the latest code to certain servers, etc.

Recently, while working from home, I kept noticing that my internet felt slow. I'd hop on over to speedtest.net and see much lower than expected results. Before calling up my ISP, I noticed that I had forgotten to disconnect from the VPN! Connected for 8-15 hours, routing all of my traffic through our company's private network! :(

So, I came up with a solution: a small ruby script that runs every 10 minutes to check whether I'm connected to the VPN, and if I have been for more than 10 minutes, yell at me.


SimplestStatus — An Enhanced Enum Implementation for Any Version of Rails

While working on a recent project, I ended up with three different models with integer-type status columns and nearly identical status-related functionality. They looked something like this:

class Post < ActiveRecord::Base
  DRAFT     = 0
  PREVIEW   = 1
  PUBLISHED = 2
  ARCHIVED  = 3

  STATUSES = {
    DRAFT     => :draft,
    PREVIEW   => :preview,
    PUBLISHED => :published,
    ARCHIVED  => :archived
  }

  STATUSES.each do |value, name|
    scope name, -> { where(status: value) }

    define_method "#{name}?" do
      status == value
    end

    define_method name do
      update_attributes(status: value)
    end
  end

  validates :status, presence: true, inclusion: { in: STATUSES.keys }
end

Having an integer-type status column gave me more flexibility over the number of statuses — as well as the flexibility to change the name of a status without having to make any database migrations (which would have been the case if I was storing strings). In my case, this was worth the tradeoff of the database having a different understanding of the data than the application.

After the third model, it was time to DRY things up. First, I thought about the simplest DSL to get me all the status functionality I needed, which led to the following:

class Post < ActiveRecord::Base
  statuses :draft,
           :preview,
           :published,
           :archived
end

As a result, SimplestStatus was born!


Searching Serialized Fields in Rails Using Postgres Arrays

In Rails, ActiveRecord allows you store and retrieve data structures like arrays and hashes in a single string or text-type database column through application-level serialization.

It is a common pattern with models having fields like tags or nicknames, where you want to be able to store an arbitrary list of strings:

class Post < ActiveRecord::Base
  serialize :tags
end

This is all fine n' dandy until you're like, "I want to find all posts tagged with either 'hobbits' or 'gandalf'!" Well..

simply


Composable SQL Queries in Rails Using Arel

If you've spent any time working with Rails, you've been using Arel. Arel is a SQL abstraction that ActiveRecord uses to build SQL queries. Arel wraps each component of the SQL query language with Ruby objects and provides an expressive DSL for composing SQL queries. When using Arel, you're mainly interacting with tables (Arel::Table) and nodes (Arel::Nodes::Node subclasses).

In a nutshell, Arel gives you the tools to build SQL queries in Ruby-land. Sounds great, right? Mostly! Documentation for Arel is pretty sparse, so it takes some digging around to figure out what all you can do with it. In this post, I'd like to save you some of that time and trouble! come


Rdio / Spotify Conversion with Hubot and Slack

We love Slack at Viget. The #music channel is my favorite; it's great for finding new music or just discussing your favorite jam. Whenever we come across something we want to share, we grab the link from either Rdio or Spotify and paste into Slack. Because there's no clear preference between the two services, I developed some custom hubot scripts to convert the URLs from one service to another.

If you're just looking for the scripts, here you go: