<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Growing Devs</title>
  <link href="http://growingdevs.com/feed.xml" rel="self" />
  <link href="http://growingdevs.com/" />
  <id>http://growingdevs.com/</id>
  <updated>2020-11-28T22:16:32+00:00</updated>
  <author>
    <name>Growing Devs</name>
    <email>growingdevs@gmail.com</email>
  </author>

  
    <entry>
      <id>http://growingdevs.com/after-code-school-career-part-two-software-boogaloo</id>
      <title>Reflecting on Code School: Career Part Two, Software Boogaloo</title>
      <link href="http://growingdevs.com/after-code-school-career-part-two-software-boogaloo.html" />
      <updated>2014-12-19T17:20:51+00:00</updated>
      <author>
        <name>Travis Valentine</name>
      </author>
      <content type="html">
        &lt;blockquote&gt;
  &lt;p&gt;“I’ve been around the block twice, now my shot nice&lt;br /&gt;
No referee but best believe out here I got stripes&lt;br /&gt;
Now that they finally consider me a legit scorer&lt;br /&gt;
Would you believe I started off as a bench-warmer?&lt;br /&gt;
Have me feelin’ like Master Splinter&lt;br /&gt;
Now the haters and commentators say ‘there’s a winner’&lt;br /&gt;
Hey, hard work pay off, now I don’t take a day off”&lt;br /&gt;
– J. Cole &lt;em&gt;The Plan&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A little over four years ago, I was sitting in my office in a U.S federal government agency bored out of my mind. Thinking about an idea I had during a recent trip home to Pennsylvania, I started researching web development. I joined a bunch of e-mail lists and bought a whole slew of books. After a while I reached out to some engineers, and many of them suggested I look into Ruby on Rails. So I did.&lt;/p&gt;

&lt;p&gt;I spent hours scouring docs, reading Stack Overflow, and reviewing some code a friend of mine wrote. After two years and some skepticism that I was doing the right thing, I entered LivingSocial’s &lt;a href=&quot;http://www.hungryacademy.com/&quot;&gt;Hungry Academy&lt;/a&gt;. It was, as the &lt;a href=&quot;http://www.washingtonpost.com/business/capitalbusiness/with-hungry-academy-livingsocial-aims-to-build-its-own-techies/2012/07/29/gJQAH5Q2IX_story.html&quot;&gt;Washington Post described&lt;/a&gt;, an experiment. More late nights ensued, and after five months I became a full-time engineer at LivingSocial.&lt;/p&gt;

&lt;p&gt;Looking back, while my path was a bit unusual at the time, my gravitation towards web development makes sense - especially considering my prior career in government. Facing the same options, Jack Dorsey described his rationale for choosing computer science over political science in a talk at &lt;a href=&quot;http://ecorner.stanford.edu/authorMaterialInfo.html?mid=2637&quot;&gt;Stanford&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I was deciding between political science at the time and computer science because I have always been fascinated by cities and at some point want to maybe potentially go into government. I’m still not quite sure if I have more effect there or more effect in programming. But I went away from political science because I realized that there are a lot of parallels between what you do in politics and what you do in government and writing policy and laws and what you do in programming. But the difference is the time scale. So, I could write a policy as a senator or as a mayor and I could see the effect maybe in eight years. But I could write that same policy and write a simulator around it and write populations around it and I could see that effect instantly with a computer. So, I went down the computer science route.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dorsey’s observation is spot-on. If I were in my previous government job, it might take years to see something come to fruition. Now I can go home with an idea, crank out some code and have a working prototype, all in a matter of days. (Granted there’s still a ton of work to go into making a prototype a reality, but I digress.) That satisfaction is what attracted me to web development and it’s one of the reasons for which I’m grateful for having been a part of Hungry Academy. But like everything else, the road to becoming an engineer wasn’t without its challenges.&lt;/p&gt;

&lt;p&gt;Much like the experiences that come from them, the challenges that code schools provide are unique. While you’re going through it, you’re aware of how much the skills you’re learning are in-demand. Then when you leave, you don’t know how in demand you are because you’re new. Looking back, there were things that were new to me that I struggled with as well as things that I had experienced before but were reinforced.&lt;/p&gt;

&lt;p&gt;First, the things that were new:&lt;/p&gt;

&lt;h2 id=&quot;imposter-syndrome-is-real&quot;&gt;Imposter syndrome is real&lt;/h2&gt;

&lt;p&gt;Coming out of a code school, it can be quite difficult to not suffer from &lt;a href=&quot;http://en.wikipedia.org/wiki/Impostor_syndrome&quot;&gt;imposter syndrome&lt;/a&gt;. You graduate and end up working alongside incredibly talented people who are on your same team, but whose journey getting there was very different: years programming as a child, college degrees, etc. Believe me, I get it. Hungry Academy wasn’t your typical code school experience. We had a sweet deal thanks to LivingSocial. If there was an ideal way to learn to code, Hungry Academy was it.&lt;/p&gt;

&lt;p&gt;It’s hard to remember, but no matter how you got there you have to do the job you were hired to do. Period. As Mike Tomlin says, &lt;a href=&quot;http://www.behindthesteelcurtain.com/2013/8/12/4613342/mike-tomlin-the-standard-is-the-standard-sign-locker-room-tight-ends-depth-chart&quot;&gt;“The Standard is the Standard”&lt;/a&gt;. If I’m given the job title of Engineer, then I have to contribute to my team just like any other person with that title.&lt;/p&gt;

&lt;p&gt;It’s up to your manager and company’s performance-based processes to address your performance and make sure you are judged on your current and future work as opposed to your past.&lt;/p&gt;

&lt;h2 id=&quot;empathy-is-necessary&quot;&gt;Empathy is necessary&lt;/h2&gt;

&lt;p&gt;One of the things I struggle with as an engineer is the concept of efficiency. I’m not opposed to it. As a matter of fact, I’m well aware that a part of my job revolves around creating it. However that doesn’t mean it always sits well with me when I do.&lt;/p&gt;

&lt;p&gt;This is because, in software development, creating efficiency sometimes correlates to someone else’s job being made obsolete. I get that this is all a part of change and innovation. I get that it is the outcome of a changing workforce that is adapting to the challenges of an information economy.&lt;/p&gt;

&lt;p&gt;But it’s still tough.&lt;/p&gt;

&lt;p&gt;A word that’s mentioned in a good number of blog posts of late is empathy. More often than not it is in respect to the people who you deal with directly. To me, it’s just as important to practice empathy with those who are both directly and indirectly affected by your work.&lt;/p&gt;

&lt;p&gt;I’ll save this for another post, but while we all believe in the power of the internet that doesn’t mean we can - and should - dismiss what it can do to existing jobs through our work.&lt;/p&gt;

&lt;p&gt;While the importance of empathy and the reality of imposter syndrome were eye-openers, the following lessons were reinforced during (and after) Hungry Academy and have been just as important to my growth as an engineer:&lt;/p&gt;

&lt;h2 id=&quot;learning-is-failure&quot;&gt;Learning is failure&lt;/h2&gt;

&lt;p&gt;And vice versa.&lt;/p&gt;

&lt;p&gt;Simply put: you likely won’t be able to get through a code school if failure scares you. After all, code school is like climbing a very high, steep hill at a frantic pace. It’s worth it at the end, but going through it just sucks at times.&lt;/p&gt;

&lt;p&gt;Reminding yourself that failure is a part of learning and accepting it goes a long way in the life of a new engineer. That applies to code school and beyond.&lt;/p&gt;

&lt;h2 id=&quot;diversity-is-important&quot;&gt;Diversity is important&lt;/h2&gt;

&lt;p&gt;During Hungry Academy, one of the hardest things to do was to not compare myself to others. There was my friend who wrote Java in his last job, and my other friend who was picking up Ruby like she had written it for years. It wasn’t by design, but when you’re in an environment where everyone knows they are vying to look attractive to an engineering team, some of us compared ourselves to each other. We knew who was doing the best and we wondered where we’d end up when the music stopped.&lt;/p&gt;

&lt;p&gt;The problem with that is that we lost sight of something: Everyone brought something to the table. That’s why we were selected in the first place.&lt;/p&gt;

&lt;p&gt;When you have a good team, it is rarely the case when a part of that team doesn’t add something to the whole. So for me to constantly get caught up in whether I was as good at something as one of my peers wasn’t productive. On its own, it didn’t really matter whether I excelled in the technical or interpersonal aspects. What mattered was that my contributions helped the team move forward in the best way possible.&lt;/p&gt;

&lt;h2 id=&quot;balance-is-paramount&quot;&gt;Balance is paramount&lt;/h2&gt;

&lt;p&gt;Sometimes, to compensate for imposter syndrome you end up working around the clock. I know I do. If you can relate to that, do yourself a favor: stop reading this article. Go for a walk. Go call someone you care about. Do something.&lt;/p&gt;

&lt;p&gt;Seriously, this article will be here when you get back. So will the new feature that might get you promoted. So will the language you think you have to learn in order to get a better job. It will all be here.&lt;/p&gt;

&lt;p&gt;What may not be is your sanity.&lt;/p&gt;

&lt;p&gt;Unlike with imposter syndrome, I wouldn’t rely much on managers doing much here. Your managers might want you to take vacation and encourage you to do so, but you’re the one who has to prioritize your life and well-being. Burning out is as real as imposter syndrome, and it won’t help your team if you do.&lt;/p&gt;

&lt;p&gt;So those are a few of the takeaways I took from my time in - and my career since - Hungry Academy. I don’t pretend to think that I speak for everyone, but I hope my perspective helps. Especially if you’re thinking about engineering as a career or even going into a code school for the first time. If you have any questions, you can find me on twitter &lt;a href=&quot;https://twitter.com/travisvalentine&quot;&gt;@travisvalentine&lt;/a&gt;.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/your-first-docker-rails-deployment</id>
      <title>A basic infrastructure with Docker, Chef, and Rails</title>
      <link href="http://growingdevs.com/your-first-docker-rails-deployment.html" />
      <updated>2014-07-26T17:48:08+00:00</updated>
      <author>
        <name>Austen Ito</name>
      </author>
      <content type="html">
        &lt;h1 id=&quot;before-we-get-started&quot;&gt;Before we get started&lt;/h1&gt;

&lt;p&gt;This tutorial expects you to have knowledge of the basic Docker concepts such as images, containers, volumes, and linking. If you aren’t familiar, take a look at &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-getting-started&quot;&gt;Getting Started with Docker&lt;/a&gt;. In this post, we’ll be building infrastructure in &lt;a href=&quot;http://www.vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; 
with the lightweight resources provided by &lt;a href=&quot;https://github.com/bflad/chef-docker&quot;&gt;Chef-Docker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our chef kitchen, where we’ll configure our environment specific variables, can be found here: &lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example&quot;&gt;Example Chef Kitchen&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;what-isnt-covered&quot;&gt;What isn’t covered&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Zero downtime deploys - Vamsee Kanakala’s talk on &lt;a href=&quot;https://www.youtube.com/watch?v=mQvIWIgQ1xg&quot;&gt;Zero Downtime Deployments with Docker&lt;/a&gt; at Garden City Ruby is helpful.&lt;/li&gt;
  &lt;li&gt;Backing up your containers&lt;/li&gt;
  &lt;li&gt;Deployment to production - I have been deploying to DigitalOcean via Chef solo, however that’s a bit outside the scope of this post.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;what-are-we-trying-to-build&quot;&gt;What are we trying to build?&lt;/h1&gt;

&lt;p&gt;It’s hard to explain even a simple infrastructure without a diagram. So this is what we’ll be building step-by-step:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dl.dropboxusercontent.com/u/4857754/instrastructure.png&quot; alt=&quot;Docker Rails Diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this diagram, each square represents a Docker container built from a Docker image. Everything a container needs to run is either found in the container (e.g. configuration files) or by
linking to other containers.&lt;/p&gt;

&lt;p&gt;The rails application is linked to a gem cache container to avoid downloading gems everytime we deploy a container.&lt;/p&gt;

&lt;h1 id=&quot;gem-cache&quot;&gt;Gem Cache&lt;/h1&gt;

&lt;p&gt;Before each section, I’ll reference the chef recipe and the Dockerfile here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/recipes/gem-cache.rb&quot;&gt;Recipe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/files/default/gem-cache/Dockerfile&quot;&gt;Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the Docker world, containers are ephemeral, which means data written to containers disappear when we redeploy a container. &lt;a href=&quot;https://docs.docker.com/userguide/dockervolumes/&quot;&gt;Docker volumes&lt;/a&gt; 
allow us to store data outside of a container. In our case, we never want to redownload a gem if it already has been downloaded.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the data volume recipe:&lt;/p&gt;

&lt;pre&gt;
  &lt;code class=&quot;language-ruby&quot;&gt;
    include_recipe 'docker'

    # 1
    cookbook_file 'Dockerfile' do
      path '/tmp/Dockerfile'
      source 'gem-cache/Dockerfile'
    end

    # 2
    docker_image 'ubuntu' do
      tag 'gem-cache'
      source '/tmp'
      action :build_if_missing
    end

    #3
    docker_container 'gem-cache' do
      image 'ubuntu:gem-cache'
      container_name 'gem-cache'
      detach true
      action :run
    end
  &lt;/code&gt;
&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The first thing we need to do is copy over our &lt;a href=&quot;http://docs.docker.com/reference/builder/&quot;&gt;Dockerfile&lt;/a&gt; into the &lt;a href=&quot;http://docker.readthedocs.org/en/v0.5.3/commandline/command/build/&quot;&gt;context&lt;/a&gt; 
of the Docker build to provide the Docker daemon access to the files when building the image.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Next we create the Docker volume image. We set the context of the build to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp&lt;/code&gt;, which is where we copied our Dockerfile
scripts.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Finally, we use the image to run a container. This container is set to run bash via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMD&lt;/code&gt; directive in the Dockerfile.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;postgres&quot;&gt;Postgres&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/recipes/postgres.rb&quot;&gt;Recipe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/files/default/postgres/Dockerfile&quot;&gt;Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at the chef recipe to build our Docker image, since there’s a lot more going on:&lt;/p&gt;

&lt;pre&gt;
  &lt;code class=&quot;bash&quot;&gt;
    # 1
    FROM austenito/ruby:2.1.2

    # 2
    RUN mkdir /postgres
    ADD Berksfile /postgres/Berksfile
    ADD solo.json /postgres/solo.json
    ADD solo.rb /postgres/solo.rb

    WORKDIR /postgres

    # 3
    RUN bash -c 'source /usr/local/share/chruby/chruby.sh; chruby 2.1.2'
    RUN berks vendor ./cookbooks
    RUN chef-solo -c solo.rb -j solo.json

    # 4
    VOLUME  [&quot;/etc/postgresql&quot;, &quot;/var/log/postgresql&quot;, &quot;/var/lib/postgresql&quot;]

    # 5
    EXPOSE 5432
    USER postgres
    CMD [&quot;/usr/lib/postgresql/9.3/bin/postgres&quot;,
         &quot;-D&quot;, &quot;/var/lib/postgresql/9.3/main&quot;, &quot;-c&quot;,
         &quot;config_file=/etc/postgresql/9.3/main/postgresql.conf&quot;]
  &lt;/code&gt;
&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Pull a pre-built &lt;a href=&quot;https://registry.hub.docker.com/u/austenito/ruby-2.1.2/&quot;&gt;Ruby 2.1.2 image&lt;/a&gt; from Docker hub. It has ruby 2.1.2 and chruby installed.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Add files in the Docker daemon context to our image.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Run chef-solo to build and configure postgres with the files we copied into our image.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Expose directories to other containers to allow backups of our data. If we didn’t do this and the container is deleted, all of our
data would be lost.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Run postgres.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our chef recipe is similar to the gem cache with a few differences:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We expose a port (5432) to other containers to allow tcp connections to this container&lt;/li&gt;
  &lt;li&gt;We use &lt;a href=&quot;https://docs.docker.com/reference/builder/#env&quot;&gt;env&lt;/a&gt; to set environmental variables before we run our container&lt;/li&gt;
  &lt;li&gt;We set which volumes from other containers that available in this container with &lt;a href=&quot;https://docs.docker.com/reference/builder/#volume&quot;&gt;volumes_from&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;
  &lt;code class=&quot;language-ruby&quot;&gt;
    ...

    if `sudo docker ps -a | grep postgres`.size == 0
      docker_container 'postgres' do
        image 'austenito/postgres:9.3'
        container_name 'postgres'
        port &quot;5432:5432&quot;
        detach true
        env [&quot;POSTGRES_USER=#{node['postgresql']['user']}&quot;,
             &quot;POSTGRES_PASSWORD=#{node['postgresql']['password']}&quot;
            ]
        volumes_from 'gem-cache'
        action :run
      end
    end
  &lt;/code&gt;
&lt;/pre&gt;

&lt;h1 id=&quot;rails-application&quot;&gt;Rails application&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/recipes/rails-example.rb&quot;&gt;Recipe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/files/default/rails-example/Dockerfile&quot;&gt;Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our Rails application container uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;link&lt;/code&gt; directive to provide
&lt;a href=&quot;https://docs.docker.com/userguide/dockerlinks/#docker-container-linking&quot;&gt;container linking&lt;/a&gt;. This exposes environment
variables with ip and port information of postgres container.&lt;/p&gt;

&lt;pre&gt;
  &lt;code class=&quot;language-ruby&quot;&gt;
    ...

    docker_container 'rails-example' do
      image 'austenito/rails-example'
      container_name 'rails-example'
      detach true
      link ['postgres:db']
      volumes_from 'gem-cache'
      action :run
      port '3000:3000'
    end
  &lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;When the rails-example container starts up, we want to be able to bundle, precompile our assets, migrate, then start our server. Specifying this inline via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMD&lt;/code&gt; directive
is a bit cumbersome, so we can specify a script to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMD&lt;/code&gt; directive, 
&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/files/default/rails-example/run.sh&quot;&gt;run.sh&lt;/a&gt;.
The script clones the latest rails-example repository, bundles, migrates, and starts unicorn.&lt;/p&gt;

&lt;h1 id=&quot;nginx&quot;&gt;Nginx&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/recipes/nginx.rb&quot;&gt;Recipe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/austenito/docker-chef-rails-example/blob/master/cookbooks/example-cookbook/files/default/nginx/Dockerfile&quot;&gt;Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike the postgres container, which uses a chef recipe for configuration, we will configure nginx manually via apt and copying over our nginx.conf file. Using the nginx 
chef recipe turns out to be a bit too compilicated for our simple infrastructure example.&lt;/p&gt;

&lt;p&gt;Other than that, there is nothing new to see in the recipe or the Dockerfile. Our Dockerfile installs nginx and we run a container with nginx with our chef recipe.&lt;/p&gt;

&lt;h1 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;/h1&gt;

&lt;p&gt;We’re ready to deploy our infrasture to vagrant. Run the following commands:&lt;/p&gt;

&lt;pre&gt;
  &lt;code class=&quot;bash&quot;&gt;
    git clone https://github.com/austenito/docker-chef-rails-example
    bundle
    berks
    vagrant plugin install vagrant-omnibus
    vagrant up
  &lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;If everything went right the first time (it always does right?), you can visit the example app at &lt;a href=&quot;http://localhost:8080/&quot;&gt;http://localhost:8080/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s ssh into our vagrant box by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vagrant ssh&lt;/code&gt; and poke around. First let see what images we created:&lt;/p&gt;

&lt;pre&gt;
  &lt;code class=&quot;bash&quot;&gt;
    sudo docker images

    REPOSITORY                TAG                 IMAGE ID
    austenito                 nginx               a10b38bf0975
    austenito/rails-example   latest              38c2ed56c811
    austenito/postgres        9.3                 88c026cf2326
    ubuntu                    gem-cache           11f9a661754b
    ubuntu                    14.04               c4ff7513909d
    austenito/ruby            2.1.2               c794944b5fa2
  &lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;These images were built by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker_image&lt;/code&gt; directive in our chef recipes. They are used to create and run the containers below:&lt;/p&gt;

&lt;pre&gt;
  &lt;code class=&quot;bash&quot;&gt;
    sudo docker ps -a

    IMAGE                           PORTS                    NAMES
    austenito:nginx                 0.0.0.0:80-&amp;gt;80/tcp       nginx
    austenito/rails-example:latest  0.0.0.0:3000-&amp;gt;3000/tcp   nginx/rails_example,rails-example
    austenito/postgres:9.3          0.0.0.0:5432-&amp;gt;5432/tcp   nginx/rails_example/db,postgres,rails-example/db
    ubuntu:gem-cache                                         gem-cache
  &lt;/code&gt;
&lt;/pre&gt;

&lt;h1 id=&quot;what-if-i-dont-want-to-build-my-images-from-the-ground-up&quot;&gt;What if I don’t want to build my images from the ground up?&lt;/h1&gt;

&lt;p&gt;Great question! Part of the power of Docker is the ability to push your images (ala git style) to &lt;a href=&quot;http://hub.docker.com/&quot;&gt;Docker Hub&lt;/a&gt; so you don’t have to rebuild images.
Ruby takes the longest to compile and I’ve set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker_image&lt;/code&gt; directive in the postgres Dockerfile to point to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;austenito/ruby:2.1.2&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://registry.hub.docker.com/u/austenito/ruby-2.1.2/&quot;&gt;Ruby 2.1.2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/how-to-pick-languages</id>
      <title>How to Pick Languages</title>
      <link href="http://growingdevs.com/how-to-pick-languages.html" />
      <updated>2014-07-14T01:03:43+00:00</updated>
      <author>
        <name>Adam Keys</name>
      </author>
      <content type="html">
        &lt;h1 id=&quot;ideas-for-choosing-your-next-language-foray&quot;&gt;Ideas for choosing your next language foray&lt;/h1&gt;

&lt;p&gt;My relationship with programming languages is sometimes problematic. You see, it’s quite easy for me to see that the grass must &lt;em&gt;clearly&lt;/em&gt; be greener on the other side of the language fence. Thus, I spend a lot of time doing anything from a light tinker to a full-blown deep dive into new or interesting languages.&lt;/p&gt;

&lt;p&gt;I’m a programming language aficionado. More often than not, a dilettante.&lt;/p&gt;

&lt;p&gt;That confessional aside, I &lt;em&gt;do&lt;/em&gt; have guidelines that help me decide when to read over language docs looking for interesting ideas, when to tinker with it if I get “the urge”, and when to do a full-blown weekend dive into a language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt; this is for personal use only. Almost none of these guidelines hold water when it comes time to decide to deploy software to production.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;My favorite reason to dive into a language is &lt;strong&gt;the creator has a very good taste in solving problems with computers or thinking about how developers think about writing programs&lt;/strong&gt;. Though they sit on very different points in the language spectrum, &lt;a href=&quot;http://www.infoq.com/presentations/Simple-Made-Easy&quot;&gt;Rich Hickey’s&lt;/a&gt; (&lt;a href=&quot;http://clojure.org&quot;&gt;Clojure&lt;/a&gt;) and &lt;a href=&quot;http://www.se-radio.net/2007/07/episode-62-martin-odersky-on-scala/&quot;&gt;Martin Odersky’s&lt;/a&gt; (&lt;a href=&quot;http://www.scala-lang.org&quot;&gt;Scala&lt;/a&gt;) both have very compelling ideas about how to design a programming language for developers such that it magnifies a developer’s ability to think about solving problems with computers. Other times, the intrigue of a language designer’s philosophy and work make it worth looking into a language even if I never intend to use it. I checked out &lt;a href=&quot;http://rsms.me&quot;&gt;Rasmus Andersson’s&lt;/a&gt; &lt;a href=&quot;http://movelang.org&quot;&gt;Move&lt;/a&gt; solely on the strength of the rest of his work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Novelty of solution&lt;/strong&gt; is an interesting angle. Some languages solve a boring problem with a novel approach. For example, &lt;a href=&quot;http://coffeescript.org&quot;&gt;CoffeeScript&lt;/a&gt; was the first language to treat JavaScript as a boring, lower-level target and layer a principled, tidier language on top of it via a translation layer. Building on top of that, I recently came across &lt;a href=&quot;http://maxtaco.github.io/coffee-script/&quot;&gt;Iced CoffeeScript&lt;/a&gt;, which takes a problem that is new to many developers, confusing callback hierarchies, and layers some CoffeeScript syntax over rewriting the nested code as linear defer/await structures. &lt;a href=&quot;http://elixir-lang.org&quot;&gt;Elixir&lt;/a&gt; is trending lately, and falls under the same scope, though it’s target is the Erlang ecosystem.&lt;/p&gt;

&lt;p&gt;Languages with &lt;strong&gt;challenging, satisfying, or interesting principles&lt;/strong&gt; are a source of intrigue. &lt;a href=&quot;http://learnyouahaskell.com&quot;&gt;Haskell’s&lt;/a&gt; principles of &lt;em&gt;extremely&lt;/em&gt; pure functional programming and type safety are a real puzzle if you’re coming from Ruby, which allows all manners of things Haskell outright forbids. Clojure’s principles, taken as a whole, can be very satisfying: write small functions passing immutable data structures, with very explicit handling of program state to compose programs that eschew complexity in favor of simplicity due to boundaries. &lt;a href=&quot;http://learnyousomeerlang.com&quot;&gt;Erlang’s&lt;/a&gt; emergent qualities are very interesting: use functions, pattern matching, and actors to implement reliable distributed systems. I saw a language that was all about making unit conversion, e.g. feet to meters, explicit in the language. Point is, some languages are fun playing around with simply to bend your brain in weird ways.&lt;/p&gt;

&lt;p&gt;Languages that &lt;strong&gt;make previously inaccessible application domains simple&lt;/strong&gt; can be a real ego boost. Right now, &lt;a href=&quot;https://developer.apple.com/swift/blog/&quot;&gt;Swift&lt;/a&gt; is attracting a lot of eyeballs as it makes developing for Apple devices far simpler than it has been in the past. In the same way, Clojure makes Lisp a little easier, Erlang makes distributed systems a slightly less enigmatic, and &lt;a href=&quot;http://golang.org&quot;&gt;Go&lt;/a&gt; makes systems programming less intimidating.&lt;/p&gt;

&lt;p&gt;A language with &lt;strong&gt;a healthy culture is worth its weight in gold&lt;/strong&gt;. If the values of the people and code in a language don’t align well, you’ll have a bad time. If they fit well within your own, you’re going to have a ton of fun. This is the most subjective of all parameters. I find the principles around Go and Clojure really intriguing and thus find them really interesting. I’m less jazzed about Scala or C++, so I “read into them” a lot less often.&lt;/p&gt;

&lt;p&gt;Some languages are worth considering solely on the &lt;strong&gt;strength of the implementation&lt;/strong&gt;. &lt;a href=&quot;http://www.lua.org&quot;&gt;Lua&lt;/a&gt; is highly regarded for its simple of design and &lt;a href=&quot;http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf&quot;&gt;the modernity of its runtime&lt;/a&gt; given the tradeoffs required in a tool designed for embedding in larger software as a scripting language. Likewise, V8 and the Hotspot JIT compiler are well regarded technologies that make considering JavaScript and Java a rationale choice despite the shortcomings of those two languages.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;not every language is cut out for an enthusiastic tinker&lt;/strong&gt;. I’m likely to skip languages that are highly experimental, highly mathematical, come from boring vendors, or are too similar to languages I already know or use. That crosses languages like Seph, Agda, or Python off my list.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;There’s half a dozen ideas to give yourself permission and treat yourself to learning a new language. Of course, the old standby excuses are pretty good too. Learning &lt;em&gt;any&lt;/em&gt; new programming language expands your brain. Every language you learn gives you more vocabulary to solve problems, no matter what languages you use on a day-to-day basis.&lt;/p&gt;

&lt;p&gt;Teaching yourself a new language is a winning proposition, you only have to decide where to start. And then learn the language. But sometimes the decision is harder than the learning!&lt;/p&gt;

&lt;p&gt;Hopefully my guidelines, and perhaps some of the languages that satisfy them, will help you next time you get that itch to explore a new programming language.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/battling-complexity-in-ruby</id>
      <title>Battling Complexity in Ruby</title>
      <link href="http://growingdevs.com/battling-complexity-in-ruby.html" />
      <updated>2014-07-05T23:14:42+00:00</updated>
      <author>
        <name>Coraline Ada Ehmke</name>
      </author>
      <content type="html">
        &lt;p&gt;Every one of our classes is an ambitious creature that seeks power through an accumulation of methods; knowledge through willful ignorance of the Law of Demeter; freedom by resisting testability; immortality through complexity. In short, they all strive for godhood.&lt;/p&gt;

&lt;p&gt;When this happens, we find the power relationship between the developer and the codebase inverted. The code controls us. We become mere handmaidens to complexity. Although our instinct might be to treat problems of complexity as Gordian knots to cut through with a single stroke of cleverness, this is a fantasy that almost never plays out well in reality. The truth is that achieving simplicity takes a lot of effort. Our best chance to win victory over complexity lies in our ability to slowly and methodically break complicated things down into smaller pieces.&lt;/p&gt;

&lt;h1 id=&quot;code-analysis&quot;&gt;Code Analysis&lt;/h1&gt;

&lt;p&gt;Just as changing code without having tests as a guiderope is a recipe for disaster, so is refactoring code without deciding in advance on success criteria. One way to establish such criteria is through the use of code analysis tools.&lt;/p&gt;

&lt;p&gt;The gallery of such tools is populated with evocatively-named rogues such as Flog, Flay, and Reek. Some, like Metric Fu, are meta-tools combining several analysis tools together to provide a more faceted view of code quality. And of course there is the SaaS solution of Code Climate, with its famous letter-grade ranking of complexity.&lt;/p&gt;

&lt;p&gt;But the results of these tools can often be overwhelming. What do you do with the list of code smells, the failing grades, the cryptic numbers?&lt;/p&gt;

&lt;p&gt;My recommendation is to start small. Identify a single metric that is easy to understand and communicate, and take steps to improve that metric.&lt;/p&gt;

&lt;h1 id=&quot;if-only&quot;&gt;If Only&lt;/h1&gt;

&lt;p&gt;It helps to define boundaries and sharpen our focus. A good first pass at reducing complexity can be to refactor conditional-heavy methods. The wedge code that most often undermines the simplicity, reusability, and clarity of our programs is the conditional. (A tax on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statements, with extra penalties for ternaries, would do more for code quality than an army of consultants equipped with Michael Feathers books.)&lt;/p&gt;

&lt;p&gt;Reducing conditionals is a good way to reduce noise in the codebase, and reveal more gnarly complexity underneath, while making positive and demonstrable progress in promoting code clarity.&lt;/p&gt;

&lt;h1 id=&quot;the-garden-of-plenty&quot;&gt;The Garden of Plenty&lt;/h1&gt;

&lt;p&gt;There are lots of code analysis tools that measure complexity, but none of them seem to agree on what complexity means. Running a suite of analysis tools using &lt;a href=&quot;https://github.com/metricfu/metric_fu&quot;&gt;MetricFu&lt;/a&gt; can demonstrate general consensus on where hotspots in the code are, but it’s easy to be overwhelmed by the half-dozen independent metrics that component tools provide. It’s also impossible to compare the results of one tool against another, because each uses independent metrics and algorithms. Is a “D” in Code Climate better or worse than an 13.2 in Flay? Once again we face a signal-to-noise problem.&lt;/p&gt;

&lt;p&gt;Surely there is a tool that specifically helps identify overuse of conditionals?&lt;/p&gt;

&lt;h1 id=&quot;the-desert-of-the-real&quot;&gt;The Desert of the Real&lt;/h1&gt;

&lt;p&gt;The best approach to identifying complex conditional logic is examining cyclomatic complexity scores. Cyclomatic complexity is derived from an analysis of the number of possible execution paths through a given piece of code. There is even a Ruby tool for measuring this, called Saikuro, and it’s already part of MetricFu.&lt;/p&gt;

&lt;p&gt;Unfortunately the output of the program didn’t serve my needs. I forked the repository with the intention of extending the program to produce output that I could better use. I discovered that the project was created in 2005 and appeared to be abandoned. The version that MetricFu used was a bespoke fork. And the code had not aged well– despite my best efforts, I found the program to be (ironically) complex and resistant to change.&lt;/p&gt;

&lt;h1 id=&quot;fukuzatsu-is-born&quot;&gt;Fukuzatsu is Born&lt;/h1&gt;

&lt;p&gt;I promise that I did not set out from the start to build my own code complexity tool. Really I didn’t. But in the end, that’s what I did.&lt;/p&gt;

&lt;p&gt;Fukuzatsu (Japanese for “complexity”) is a command-line tool packaged as a Ruby gem. It is invoked by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fuku check&lt;/code&gt; command, which takes a file path as an argument. Output options can be specified by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--format&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-f&lt;/code&gt;) flag, and include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;html&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;csv&lt;/code&gt;, and of course &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;text&lt;/code&gt; (default). To facilitate CI integration, the program can be passed a minimum threshold (via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--threshold&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t&lt;/code&gt;), which in turn triggers an exit condition that CI applications can use to ensure that code meets your standards.&lt;/p&gt;

&lt;h2 id=&quot;stdout-output&quot;&gt;STDOUT Output&lt;/h2&gt;

&lt;p&gt;Good UNIX programs accept text input and return text output, allowing them to be used in the composition of powerful ad-hoc programs using the pipe operator (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt;). Fukuzatsu’s default mode accepts a file path and returns text output. So for example if we want to analyze the largest file in our project, we can do this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ find . -type f -exec ls -s {} \; | sort -n -r | head -1 | xargs fuku check $1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This composite program uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; to list files in order of size, piped to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;head&lt;/code&gt; to grab the first on the list, and passing the result to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fuku&lt;/code&gt; for analysis. The output is:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Analyzer    17
Analyzer  #initialize 0
Analyzer  #complexity 1
Analyzer  #extract_methods  1
Analyzer  #extract_class_name 2
Analyzer  #text_at  0
Analyzer  #find_class 4
Analyzer  #extend_graph 0
Analyzer  #methods_from 4
Analyzer  #parent_node? 1
Analyzer  #parse! 1
Analyzer  #parsed 1
Analyzer  #traverse 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This says that the overall complexity of the Analyzer class is 17. Each method is listed with its name and complexity value. This output is suitable for piping out to other programs, or to a file for later perusal:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ls -S ./lib/*/** | head -1 | xargs fuku check $1 &amp;gt; results.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This could be handy for running via a cron job to measure how complexity changes over time.&lt;/p&gt;

&lt;h2 id=&quot;csv-output&quot;&gt;CSV Output&lt;/h2&gt;

&lt;p&gt;If you want to pull your analysis into a spreadsheet, the csv option is right for you:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ fuku check lib/foo/bar.rb -f csv
Results written to:
doc/fukuzatsu/lib/foo/bar.rb.csv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;ci-output&quot;&gt;CI Output&lt;/h2&gt;

&lt;p&gt;To better integrate with a continuous integration system, set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t&lt;/code&gt; (threshold) flag with the maximum allowed complexity level:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ fuku check lib/fukuzatsu/complex.rb -t 7
Complex   17
Complex #initialize 0
Complex #complexity 1
Complex #extract_methods  1
Complex #extract_class_name 2
Complex #text_at  0
Complex #find_class 4
Complex #extend_graph 0
Complex #methods_from 4
Complex #parent_node? 1
Complex #parse! 1
Complex #parsed 1
Complex #traverse 2

Results written to:
doc/fukuzatsu/lib/fukuzatsu/complex.rb

Maximum complexity is 17, which is greater than the threshold of 7.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When a threshold is set, the exit status will be non-zero if the threshold is met or exceeded.&lt;/p&gt;

&lt;h2 id=&quot;html-output&quot;&gt;HTML Output&lt;/h2&gt;

&lt;p&gt;For an interactive report, use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-f html&lt;/code&gt; flag:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ fuku check lib/my_project/ -f html
Results written to:
doc/fukuzatsu/index.htm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will generate a tree of HTML files under the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./doc/fukuzatsu&lt;/code&gt; directory, complete with an index file at the root path. The generated pages display sortable and filterable tables of files or methods with their complexity values.&lt;/p&gt;

&lt;h1 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h1&gt;

&lt;p&gt;I’m finding Fukuzatsu to be a great tool for helping me identify complexity resulting from too many conditionals in my code. In fact, I use it regularly to measure itself and try to keep the numbers from going up from merge request to merge request.&lt;/p&gt;

&lt;p&gt;I hope that you’ll check out Fukuzatsu and try it in your refactoring project. And of course bug reports, feature requests, and merge requests are always welcome! It’s available on RubyGems right now (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gem install fukuzatsu&lt;/code&gt;), and installation and usage instructions are provided on  &lt;a href=&quot;https://gitlab.com/coraline/fukuzatsu/tree/master&quot;&gt;GitLab&lt;/a&gt;.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/building-a-conference-from-scratch</id>
      <title>Building a Conference From Scratch</title>
      <link href="http://growingdevs.com/building-a-conference-from-scratch.html" />
      <updated>2014-05-23T02:06:31+00:00</updated>
      <author>
        <name>Jeremy Carbaugh</name>
      </author>
      <content type="html">
        &lt;p&gt;Anyone who knows me well will tell you that I have a terrible habit of reinventing the wheel. It can get &lt;a href=&quot;http://sunlightfoundation.com/blog/2011/11/02/on-cms-diy/&quot;&gt;really, really bad&lt;/a&gt; at times. I know there is a lot of great software out there, but there is always the smallest little thing that keeps it from being perfect. I know I can do better! So imagine the itch I get when someone says “Hey, we have to run a conference. What software do we need?”&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://transparencycamp.org/&quot;&gt;TransparencyCamp&lt;/a&gt; is an open government unconference run by my employer, the &lt;a href=&quot;http://sunlightfoundation.com/&quot;&gt;Sunlight Foundation&lt;/a&gt;. We started TransparencyCamp in 2009 with just under 100 attendees. It was a scrappy little event, with most of us having very little experience running a conference. On May 30-31, 2014, we’ll be hosting over &lt;em&gt;550 people from across the world&lt;/em&gt; at TransparencyCamp 2014.&lt;/p&gt;

&lt;p&gt;As the conference has grown, we’ve had the chance to build numerous projects that help us run the event. Sure, we could have used existing software to do it, but it’s way more fun to build our own.&lt;/p&gt;

&lt;h2 id=&quot;the-badges-and-registration&quot;&gt;The Badges and Registration&lt;/h2&gt;

&lt;p&gt;In previous years we used &lt;a href=&quot;http://eventbrite.com&quot;&gt;Eventbrite&lt;/a&gt; for registration and ticketing. It was a great system; they even provide a mobile app that can be used at the check-in desk to scan badges. Never wanting to settle for good enough, we figured out the format of the data stored in the Eventbrite-generated barcodes and encoded our own as QR codes that were printed on the badges. These badges could still be read by the app provided by Eventbrite, but when used in conjunction with the Eventbrite API, we could manage the process using our own systems.&lt;/p&gt;

&lt;p&gt;This year we’ve gone with a completely homegrown registration and ticketing system writen in &lt;a href=&quot;https://www.python.org/&quot;&gt;Python&lt;/a&gt; and &lt;a href=&quot;https://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt;. It uses &lt;a href=&quot;https://www.braintreepayments.com/&quot;&gt;Braintree&lt;/a&gt; for processing payments, sends email with &lt;a href=&quot;https://postmarkapp.com&quot;&gt;Postmark&lt;/a&gt;, and has an API for accessing ticket information. The system also takes care of generating all of the QR codes that are printed on the badges.&lt;/p&gt;

&lt;p&gt;Having all of the ticket information in our own system allows us to tie in other aspects of the event. We have several food trucks available for lunch (covered by the price of a ticket) and will have staff at each truck scanning the QR code on attendee badges when they get their food. This isn’t just to make sure people only eat one meal, it will also provide us with valuable data about which trucks were the most popular and how fast each truck was able to serve customers. We’ll be displaying this information in real-time at the event.&lt;/p&gt;

&lt;h2 id=&quot;the-schedule&quot;&gt;The Schedule&lt;/h2&gt;

&lt;figure&gt;
&lt;a href=&quot;https://www.flickr.com/photos/sunlightfoundation/8717344451&quot; title=&quot;An attentive crowd in front of &amp;quot;The Wall&amp;quot; by sunlightfoundation, on Flickr&quot;&gt;&lt;img src=&quot;https://farm8.staticflickr.com/7422/8717344451_bb0ccff6f2.jpg&quot; width=&quot;100%&quot; alt=&quot;An attentive crowd in front of &amp;quot;The Wall&amp;quot;&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;An attentive crowd in front of &amp;quot;The Wall&amp;quot; by sunlightfoundation&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;What would an unconference be without a giant wall for schedule making? Until last year we used a paper-based wall where people would write session information on cards and tape them to the wall. We decided to try something different in 2013 (partially due to the venue not allowing tape on the walls) and go completely digital. Sessions were submitted via laptops or paper and entered into a database. This database powered both the web site and a giant HTML calendar view that was cast onto the wall using three short throw projectors.&lt;/p&gt;

&lt;p&gt;We’re moving back to paper this year due to readability issues with the digital wall (distance, text size, clarity, etc.), but sessions will still be submitted electronically. Cards for each session will be printed and hung on the wall by staff.&lt;/p&gt;

&lt;h2 id=&quot;the-counselors&quot;&gt;The Counselors&lt;/h2&gt;

&lt;p&gt;Who wants to come to a conference and see the staff fumbling through stacks of papers or have to stand around while a staff member that can help solve your problem is located?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://assets.sunlightfoundation.com.s3.amazonaws.com/CampCounselor.png&quot; style=&quot;float: right; margin: 0 0 1em 1em;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Almost everything staff need to do at TransparencyCamp is handled by a custom iOS app, Camp Counselor. This includes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;scanning badges to check-in attendees&lt;/li&gt;
  &lt;li&gt;viewing check-in stats and other important day-of information&lt;/li&gt;
  &lt;li&gt;scanning badges to “rent” display adapters and other equipment&lt;/li&gt;
  &lt;li&gt;marking equipment as returned or sending a polite email to people that have run off with something&lt;/li&gt;
  &lt;li&gt;scanning badges (lots of scanning) to redeem lunch at food trucks&lt;/li&gt;
  &lt;li&gt;scanning badges to register attendees for API keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this information is stored on a central server, Lodge, that has a simple JSON API. The Lodge is a Python web app written in &lt;a href=&quot;http://flask.pocoo.org/&quot;&gt;Flask&lt;/a&gt; and hosted on &lt;a href=&quot;http://heroku.com&quot;&gt;Heroku&lt;/a&gt;. The iOS app itself is a small client to the API using &lt;a href=&quot;http://afnetworking.org&quot;&gt;AFNetworking&lt;/a&gt; for making calls to the server.&lt;/p&gt;

&lt;p&gt;We distribute the app to staff devices via &lt;a href=&quot;http://testflightapp.com&quot;&gt;TestFlight&lt;/a&gt;. If an emergency fix needs to be pushed out, TestFlight can force people to upgrade, ensuring that everyone is using the latest version.&lt;/p&gt;

&lt;h2 id=&quot;the-other-stuff&quot;&gt;The Other Stuff&lt;/h2&gt;

&lt;figure&gt;
&lt;a href=&quot;https://www.flickr.com/photos/bytemarks/6980599906&quot; title=&quot;Transparency Camp 2012 by Burt Lum, on Flickr&quot;&gt;&lt;img src=&quot;https://farm9.staticflickr.com/8148/6980599906_146e560058.jpg&quot; width=&quot;100%&quot; alt=&quot;Transparency Camp 2012&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;Transparency Camp 2012 by Burt Lum&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Since it’s the small details that really make a difference, we’ve built out a number of other interesting things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HTML-based information screens placed around the event that show current schedule information&lt;/li&gt;
  &lt;li&gt;HTML-based slideshows shown on screens that cycle through tweets and Instagrams from the event&lt;/li&gt;
  &lt;li&gt;live-streaming of keynote talks&lt;/li&gt;
  &lt;li&gt;a responsive web site, optimized for day-of use on mobile&lt;/li&gt;
  &lt;li&gt;an interactive SMS interface to the schedule&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;There is no doubt that we could have run TransparencyCamp throughout the years without spending all of this time on custom development. It would have been a perfectly fine conference, but we don’t want to settle for “fine” at Sunlight. The extra effort that we put into the systems and the experience sets the tone for the event. It shows that we care about the little details. It shows that we seek to inspire. It shows that TransparencyCamp is unlike any other conference you’ve been to.&lt;/p&gt;

&lt;p&gt;It is important to understand all of the downsides that come along with the decision to embark on your own path and reinvent the wheel. It’s not something that should be taken lightly. However, if done with understanding and purpose, extreme DIY can yield fantastic (and super fun) results.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source code for the Camp Counselor iOS app and Lodge server will be made available shortly after TransparencyCamp 2014 on the &lt;a href=&quot;https://github.com/sunlightlabs&quot;&gt;Sunlight Labs GitHub account&lt;/a&gt;. The TransparencyCamp site, registration, and scheduling systems have &lt;a href=&quot;https://github.com/sunlightlabs/tcamp&quot;&gt;already been published&lt;/a&gt;. These projects, like all good software, are available under the BSD license.&lt;/em&gt;&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/stop-using-rubygems-and-start-using-bower</id>
      <title>Use Bower for managing front-end assets in Rails</title>
      <link href="http://growingdevs.com/stop-using-rubygems-and-start-using-bower.html" />
      <updated>2014-04-09T16:34:50+00:00</updated>
      <author>
        <name>Dave Copeland</name>
      </author>
      <content type="html">
        &lt;p&gt;Rails’ history with front-end asset management is somewhat complex, involving a mixture of gems and manual file management.
Fortunately, there’s now a better way—Bower.&lt;/p&gt;

&lt;p&gt;Rails 4.0.4 depends on version 2.2.x of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jquery-rails&lt;/code&gt; gem which in turn bundles 1.9.1 of JQuery. Does that make &lt;em&gt;any&lt;/em&gt; sense?  The latest official release of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;angular-ui-bootstrap-rails&lt;/code&gt; is 0.9.0, which is at least a version behind the current release of the Angular UI bootstrap directives.  When will it be updated?  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chosen-rails&lt;/code&gt; version 1.1.0 bundles an old version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chosen-jquery&lt;/code&gt; that has never been officially released.  What?&lt;/p&gt;

&lt;p&gt;As recent as a year and a half ago, this mess was the only sane way to manage front-end assets in a Rails app. You’d have to create a Rails Engine inside a gem that made the assets available.&lt;/p&gt;

&lt;p&gt;When you want to use an asset in your Rails app, you have to navigate the insanity above to figure out what version you are using.  If what you want isn’t provided by a gem, the “best practice” was to just download the files and throw them in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vendor/assets&lt;/code&gt;.  If your assets had inter-dependencies, you better watch out.  And if you had a non-Ruby application - forget about it.&lt;/p&gt;

&lt;p&gt;Now, there’s a better way—&lt;a href=&quot;http://bower.io&quot;&gt;Bower&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bower was created by Twitter to manage front-end assets.  It’s not particular to Rails (and, like many JavaScript command-line tools, it uses NodeJS), but it works similarly to RubyGems and Bundler.  You simply create a file in your project that describes what packages you want, and use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bower&lt;/code&gt; command-line app to install them.  Bower also knows about inter-asset dependencies.  Most importantly, Bower allows you to specify &lt;em&gt;directly&lt;/em&gt; what version of an asset you want.&lt;/p&gt;

&lt;p&gt;I’m not sure why Rails doesn’t provide a better tool for this.  Perhaps someday it will, but for now, Bower is going to make your
life so much easier, especially if you use a lot of front-end assets, or need to share private assets between your apps.&lt;/p&gt;

&lt;h2 id=&quot;setting-it-up&quot;&gt;Setting it up&lt;/h2&gt;

&lt;p&gt;The handy &lt;a href=&quot;https://github.com/42dev/bower-rails&quot;&gt;bower-rails&lt;/a&gt; gem creates some Rake tasks for you, but also allows you to specify your dependencies in a succinct Gemfile-like format (called, naturaly, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bowerfile&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;gem 'bower-rails'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It’s important to note that this doesn’t include the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bower&lt;/code&gt; command-line app, it just calls into it.  You’ll need to install bower, likely with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install bower&lt;/code&gt; (which requires installing Node and NPM.  I know that’s a potential yak-shaving thing, but it’ll be worth it).&lt;/p&gt;

&lt;p&gt;Then place &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bowerfile&lt;/code&gt; in your root directory.  Here’s an example of one that uses AngularJS, version 1.2.13:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;asset 'angular', '1.2.13'
asset 'angular-route'
asset 'angular-resource'
asset 'angular-mocks'
asset 'angular-ui-bootstrap-bower'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You then install them with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rake bower:install&lt;/code&gt;.  If there are any verison incompatibilities, they will generate errors, just
like you’d see in Bundler.  Everything gets downloaded to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vendor/assets/bower_components&lt;/code&gt; by default.  Because this isn’t
standard Rails, you’ll need to add this to your asset pipeline configuration in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config/application.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;config.assets.paths &amp;lt;&amp;lt; 
  Rails.root.join(&quot;vendor&quot;,&quot;assets&quot;,&quot;bower_components&quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And, finally, add your newly-managed assets to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application.js&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;//= require angular/angular
//= require angular-resource/angular-resource
//= require angular-route/angular-route
//= require angular-ui-bootstrap-bower/ui-bootstrap.js
//= require angular-ui-bootstrap-bower/ui-bootstrap-tpls.js
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s it!  Now, your front-end assets can be managed in a sane way.  But this is only part of it.  Because Bower is so simple,
it’s easy to use it to manage internal, private assets that you don’t (or can’t) share with the outside world.&lt;/p&gt;

&lt;h2 id=&quot;managing-private-assets&quot;&gt;Managing Private Assets&lt;/h2&gt;

&lt;p&gt;I work at &lt;a href=&quot;http://tech.stitchfix.com/blog&quot;&gt;Stitch Fix&lt;/a&gt;, and we have several applications that serve many different purposes.  Still, they all interact with our inventory in various ways.  Although much of that information is stored in a shared database, the official color swatches of our inventory aren’t stored there.  They had been copied between various apps.  We’re now using Bower to share them.  This way, when we add new colors or update the swatches, the whole team knows, and we can roll out the updates in an organized way.&lt;/p&gt;

&lt;p&gt;Here’s how to set that up.&lt;/p&gt;

&lt;p&gt;Since a Bower version string can be a git url, a value like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git@github.com/stitchfix/colors#1.0.3&lt;/code&gt; will tell Bower to get assets from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stitchfix/colors&lt;/code&gt; repo, at whatever version is tagged 1.0.3.  All we have to do is put a small file named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; into that repo:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;name&quot;: &quot;colors&quot;,
  &quot;version&quot;: &quot;1.0.3&quot;,
  &quot;main&quot;: [
    &quot;colors.css&quot;
  ],
  &quot;dependencies&quot;: { },
  &quot;devDependencies&quot;: { },
  &quot;ignore&quot;: [
    &quot;**/.*&quot;,
    &quot;bower_components&quot;,
    &quot;test&quot;
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bowerfile&lt;/code&gt;, you just use the git url:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;asset 'colors', 'git@github.com/stitchfix/colors#1.0.3'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And, we add it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application.css.scss&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;#= colors/colors
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s it!  Now you can manage internal assets without RubyGems in a sane way.  This means that all your front-end assets, public
and private, are managed from one clear location, and you can re-use your internal assets for non-Ruby apps, to boot.&lt;/p&gt;

&lt;p&gt;Next time you are tempted to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt; to manage your assets, try Bower instead.&lt;/p&gt;


      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/refactoring-rails-views-with-simplest-view</id>
      <title>Refactoring Rails Views with SimplestView</title>
      <link href="http://growingdevs.com/refactoring-rails-views-with-simplest-view.html" />
      <updated>2014-01-29T16:34:50+00:00</updated>
      <author>
        <name>Tony Pitale</name>
      </author>
      <content type="html">
        &lt;p&gt;Most of the projects I’ve worked with grow in similar ways. Code often ends up where it is &lt;em&gt;easiest&lt;/em&gt; to place it. For code in our Rails “Views”, under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/views&lt;/code&gt;, that’s either in the controller (with lots of instance variables assigned), in ApplicationHelper (shared with every view), or in the view templates themselves.&lt;/p&gt;

&lt;p&gt;I’m going to try to address each of these scenarios, and show you how to refactor them into much simpler code, using &lt;a href=&quot;https://github.com/tpitale/simplest_view&quot;&gt;SimplestView&lt;/a&gt;. But first, a little background.&lt;/p&gt;

&lt;h2 id=&quot;the-rails-way&quot;&gt;The Rails Way&lt;/h2&gt;

&lt;p&gt;In Rails, our ERB templates go under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/views&lt;/code&gt;. There is a logical structure to how they are organized. This is The Rails Way. By convention, the views for a controller &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SalesController&lt;/code&gt; goes inside the folder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/views/sales&lt;/code&gt;. Further, each action gets a file inside the sales folder, using the name of the action as the filename.&lt;/p&gt;

&lt;p&gt;The tricky bit is these Rails “Views” aren’t really view objects. The ERB templates we build, are rendered inside the context of an instance of an &lt;strong&gt;anonymous&lt;/strong&gt; class, which inherits it’s rendering abilities from ActionView::Base.&lt;/p&gt;

&lt;p&gt;But why an anonymous class? Why does Rails hide this away from us completely?&lt;/p&gt;

&lt;h2 id=&quot;with-simplestview&quot;&gt;With SimplestView&lt;/h2&gt;

&lt;p&gt;Now, if we set up our Rails application to use &lt;a href=&quot;https://github.com/tpitale/simplest_view#usage&quot;&gt;SimplestView&lt;/a&gt;, we get clear, &lt;em&gt;conventional&lt;/em&gt; access to these previously hidden view classes. We give them a &lt;strong&gt;name&lt;/strong&gt;. By convention, that name will match the action, and be placed inside a folder matching the controller name.&lt;/p&gt;

&lt;p&gt;For our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SalesController&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#index&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#show&lt;/code&gt; we would have classes named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sales::IndexView&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sales::ShowView&lt;/code&gt; (which inherit from ActionView::Base) inside of a folder in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/views/sales&lt;/code&gt;. &lt;strong&gt;Note:&lt;/strong&gt; SimplestView has you move your ERB into a more aptly named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/templates&lt;/code&gt; folder to keep things cleanly separated, and to give you a nice Rails-y place to put your new views.&lt;/p&gt;

&lt;p&gt;Now that we have that out of the way, let’s get into some refactorings!&lt;/p&gt;

&lt;h2 id=&quot;applicationhelper-overload&quot;&gt;ApplicationHelper Overload&lt;/h2&gt;

&lt;p&gt;How often have you had to dig through an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationHelper&lt;/code&gt; that simply contains &lt;em&gt;every&lt;/em&gt; single helper in the whole project? I’ve seen projects with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationHelper&lt;/code&gt; thousands of lines long.&lt;/p&gt;

&lt;p&gt;Let’s look at a specific method that we can refactor, and get it out of there!&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;def format_tax_rate(value)
  '%.2f%' % (value.to_f * 100)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And it might be used in our ERB like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;&amp;lt;%= format_tax_rate(@sale.state_sales_tax) %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is some very simple code. It’s a naive approach to formatting the decimal value as a percentage to two decimal places.&lt;/p&gt;

&lt;p&gt;More importantly, it’s only &lt;em&gt;really&lt;/em&gt; needed in one or two views to display a formatted sales tax rate. Why then, should it clutter up our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApplicationHelper&lt;/code&gt; in order to be shared? And what happens when you have 10, 20, or more small methods just like this one?&lt;/p&gt;

&lt;p&gt;With SimplestView, we can move the method to a better place. If we were to handle this in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sales::IndexView&lt;/code&gt;, for example, we could do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Sales::IndexView &amp;lt; ActionView::Base
  def formatted_state_sales_tax
    '%.2f%' % (@sale.state_sales_tax.to_f * 100)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, what did we do here?&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We made our view match the conventions. For the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SalesController#index&lt;/code&gt; controller and action, we’ll use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sales::IndexView&lt;/code&gt; as the context for the template now found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/templates/sales/index.html.erb&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;We made a nicely named method which contains just the formatting we need.&lt;/li&gt;
  &lt;li&gt;We use the instance method for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@sale&lt;/code&gt;, which we assigned in our controller, and is accessible to us inside of the view.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What are the benefits? Well, we get nicer encapsulation. We don’t have to expose the instance variable inside of the ERB for this particular case&lt;/p&gt;

&lt;h2 id=&quot;hello-oo&quot;&gt;Hello OO!&lt;/h2&gt;

&lt;p&gt;After this section, I want to make a quick aside to point out something important. With SimplestView, we’re back to using Ruby as the Object-Oriented language that it is! If we need to share code, we make a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module&lt;/code&gt; to mixin. Or, if it makes sense, we can use inheritence.&lt;/p&gt;

&lt;p&gt;If we have another method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;formatted_county_sales_tax&lt;/code&gt;, we can extract a method to do the formatting. Then, if that new formatting method is used in multiple views, it’s as easy as extracting a module like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SalesTaxFormattable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In addition, we can now &lt;strong&gt;easily&lt;/strong&gt; test, and refactor this view because it’s just a Ruby class.&lt;/p&gt;

&lt;h2 id=&quot;controller-assignment&quot;&gt;Controller Assignment&lt;/h2&gt;

&lt;p&gt;One of the more troubling ways I’ve seen developers cope with growing complexity in their ERB templates has been to move calculations and logic BACK into the controller.&lt;/p&gt;

&lt;p&gt;What started out as an action that assigns a single instance variable, baloons into methods full of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;before_action&lt;/code&gt; (previously &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;before_filter&lt;/code&gt;) calls to assign and calculate many instance variables.&lt;/p&gt;

&lt;p&gt;Let’s refactor an example:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class SalesController &amp;lt; ApplicationController
  def show
    @sale = Sale.find(params[:id])
    @purchase_count = @sale.purchases.count
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we can output both data about our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@sale&lt;/code&gt;, but we can also output our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@purchase_count&lt;/code&gt; number, too.&lt;/p&gt;

&lt;p&gt;Instead, let’s do it with SimplestView.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Sales::ShowView &amp;lt; ActionView::Base
  def purchase_count
    @purchase_count ||= @sale.purchases.count
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we can still output our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;purchase_count&lt;/code&gt; in our template, without cluttering our controller!&lt;/p&gt;

&lt;h2 id=&quot;erb-templates&quot;&gt;ERB Templates&lt;/h2&gt;

&lt;p&gt;By now, it may be clear what I’m going to say. But, I’ll say it anyway.&lt;/p&gt;

&lt;p&gt;Extraneous logic in your ERB templates is &lt;em&gt;very&lt;/em&gt; likely to be a code smell. Extensive branching logic, local variable assignment, etc. Time to get it out!&lt;/p&gt;

&lt;p&gt;Inside of our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SalesController#show&lt;/code&gt; action, we’ll likely render the template found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show.html.erb&lt;/code&gt;. It might have some code like:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;&amp;lt;% if @sale.starts_on &amp;lt;= Date.today &amp;amp;&amp;amp; @sale.ends_on &amp;gt; Date.today %&amp;gt;
  On Sale!
&amp;lt;% else %&amp;gt;
  Sale Starts On: &amp;lt;%= @sale.starts_on.strftime(&quot;%B %d, %Y&quot;) %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are two things in this code that we really don’t need. Both the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; conditional and the date formatting code can be encapsulated in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sales::ShowView&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Sales::ShowView &amp;lt; ActionView::Base
  def active_sale?
    @sale.starts_on &amp;lt;= Date.today &amp;amp;&amp;amp; @sale.ends_on &amp;gt; Date.today
  end

  def formatted_start_date
    @sale.starts_on.strftime(&quot;%B %d, %Y&quot;)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is probably my favorite refactoring. And, it is likely to be the one you will use on a regular basis.&lt;/p&gt;

&lt;h2 id=&quot;but-why&quot;&gt;But Why?&lt;/h2&gt;

&lt;p&gt;The benefits of these changes might not be the biggest pain you feel in your code, day to day. But together, all of the little changes you get to make,  the added ease of refactoring, and the extra convention, make it a whole lot easier to write well-factored, maintainable code, every day.&lt;/p&gt;

&lt;p&gt;I’m using &lt;a href=&quot;https://github.com/tpitale/simplest_view&quot;&gt;SimplestView&lt;/a&gt; daily, in as many of my projects as possible. Not because the code I already have is horrendous, and not because there are no alternatives to refactor and clean up my code. I’m using it because it enables functionality in Rails that should be available already, and it gives me the conventions I kept searching for.&lt;/p&gt;

&lt;p&gt;If SimplestView doesn’t strike your fancy, you can go the decorator route with the fantastic &lt;a href=&quot;https://github.com/drapergem/draper&quot;&gt;Draper&lt;/a&gt; gem. Both Draper and SimplestView accomplish very similar things. Regardless, you should try using one of them, and see how it helps you clean up your code.&lt;/p&gt;


      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/a-beginner-s-take-on-rubymotion</id>
      <title>A Beginner's Take on RubyMotion</title>
      <link href="http://growingdevs.com/a-beginner-s-take-on-rubymotion.html" />
      <updated>2013-11-05T17:25:14+00:00</updated>
      <author>
        <name>Travis Valentine</name>
      </author>
      <content type="html">
        &lt;blockquote&gt;
  &lt;p&gt;“A little over a year ago I was in bondage,
and now I’m back out here reaping the blessings
and getting the benefits that go along with it”&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Pimp C’s last interview, from Jay-Z’s &lt;em&gt;FuckWithMeYouKnowIGotIt&lt;/em&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Like many others, I initially started to program because I had an idea. After a brief stint with PHP, I dove into Ruby/Rails and started developing my app, &lt;a href=&quot;http://yourturn.org&quot;&gt;YourTurn&lt;/a&gt;. During development, there was a lot I wanted to learn about the technologies (and their minutiae) I was discovering, but my focus was getting something tangible to appear on my screen. This not only helped me prototype my app, but also drove me to learn more. (Topic for a future post? You bet.)&lt;/p&gt;

&lt;p&gt;When I set out to make an iOS app for YourTurn, I faced a similar decision: either learn a new language - Objective C - or utilize something I was more familiar with to get something done. To be honest, I didn’t really consider the latter until I heard about RubyMotion, and when I did the choice was easy.*&lt;/p&gt;

&lt;p&gt;You can learn more about RubyMotion on its &lt;a href=&quot;http://www.rubymotion.com/&quot;&gt;website&lt;/a&gt;, but I want to use my inaugural post here to highlight a few of the benefits from the perspective of a new Ruby developer. First: RubyMotion’s use of, well, Ruby.&lt;/p&gt;

&lt;p&gt;For example, here’s Objective-C syntax:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objectivec&quot;&gt;[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here’s RubyMotion:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I don’t know about you, dear reader, but I find the RubyMotion way more readable as well as easier to type.**&lt;/p&gt;

&lt;p&gt;As a beginner, a technology is only as valuable to me as the community supporting it. From the folks at HipByte to the authors of its many &lt;a href=&quot;http://rubymotion-wrappers.com/&quot;&gt;wrappers and libraries&lt;/a&gt;, it’s clear that the folks behind RubyMotion want it to succeed. I’m less than a year into the toolchain but I can confidently say I wouldn’t have been able to release version 1.0.0 of my app if it weren’t for resources like Clay Allsopp’s &lt;a href=&quot;http://rubymotion-tutorial.com/&quot;&gt;tutorial&lt;/a&gt; and &lt;a href=&quot;http://pragprog.com/book/carubym/&quot;&gt;PragProg book&lt;/a&gt;, as well as &lt;a href=&quot;http://bubblewrap.io/&quot;&gt;BubbleWrap&lt;/a&gt;, &lt;a href=&quot;https://github.com/clayallsopp/formotion&quot;&gt;Formotion&lt;/a&gt;, and &lt;a href=&quot;https://github.com/rubymotion/sugarcube&quot;&gt;Sugarcube&lt;/a&gt;. Resources like these continue to grow each day, and I know I’ll continue to lean on them as I release future versions.&lt;/p&gt;

&lt;p&gt;For me though, the best thing about RubyMotion is that it removes extraneous complexity from learning about Apple’s APIs. By not having to worry about areas in which I really lack expertise (namely Xcode and Objective-C) I can focus on making my app better. Of course, as I become more familiar with the APIs I could move to learning more about Objective-C if I wanted. But again, I wouldn’t have that choice without RubyMotion. With it I can prioritize learning the things that help me reach my ultimate goal of improving my app quickly.&lt;/p&gt;

&lt;p&gt;So am I saying RubyMotion is for everyone? No. It’s obviously best for people with varying degrees of Ruby knowledge.&lt;/p&gt;

&lt;p&gt;Is it perfect? No. A few downsides are that:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It is not fully &lt;a href=&quot;http://merbist.com/2012/05/04/macruby-on-ios-rubymotion-review/&quot;&gt;open source&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;It has had some big issues like &lt;a href=&quot;http://joshsymonds.com/blog/2013/06/26/why-im-not-using-rubymotion-in-production/&quot;&gt;RM-3&lt;/a&gt; (which, in fairness was prioritized and resolved by HipByte).&lt;/li&gt;
  &lt;li&gt;It is a bit &lt;a href=&quot;https://groups.google.com/d/msg/rubymotion/-5QkGWvo9ew/epqVwJ2I7T8J&quot;&gt;tricky with blocks&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;The license is pricey at &lt;a href=&quot;http://sites.fastspring.com/hipbyte/product/rubymotion&quot;&gt;$199.99&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Collectively, these issues represent exactly what RubyMotion is: a growing toolchain from a bootstrapped business. Aside from the price, they shouldn’t dissuade anyone from getting their hands dirty.&lt;/p&gt;

&lt;p&gt;Simply put: for Ruby developers, RubyMotion provides a lower barrier of entry to iOS Development. For beginners like me, it’s the best tool to use if you want to get an app out quickly. For that, I’m grateful to HipByte and the community behind RubyMotion.&lt;/p&gt;

&lt;p&gt;* I know there are other frameworks that utilize technologies such as HTML/CSS/JavaScript but I haven’t seen any that deliver experiences similar to those that come from native apps. Perhaps these frameworks are the future - and I’ll certainly keep an eye on them - but it’s just not there yet.&lt;/p&gt;

&lt;p&gt;** Granted, this is because my background is in Ruby and that’s all I know. But still.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/ruby-resty</id>
      <title>Ruby Resty</title>
      <link href="http://growingdevs.com/ruby-resty.html" />
      <updated>2013-09-30T11:50:43+00:00</updated>
      <author>
        <name>Austen Ito</name>
      </author>
      <content type="html">
        &lt;p&gt;I spend a lot of my time working with REST APIs. At home, at work, at
hackathons, it’s GET this and POST that. &lt;a href=&quot;https://github.com/micha/resty&quot;&gt;Resty&lt;/a&gt; is an amazing tool to
simplify sending multiple HTTP requests with the same data and headers. My
favorite part is having per-host configuration so you never have to worry about
remembering your cryptic, hashed API keys and header names.&lt;/p&gt;

&lt;p&gt;It’s such a great tool, except resty currently &lt;a href=&quot;https://github.com/micha/resty/issues/38&quot;&gt;doesn’t work in zsh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After thinking about it, a shell script isn’t the best approach for community development. Coming from a
Ruby background, shell script syntax is so &lt;em&gt;hard to read&lt;/em&gt;. What about adding functionality to Resty? 
Can I add a new command that Resty supports? Can I have nice tests documenting functionality? 
How about some continuous integration?&lt;/p&gt;

&lt;p&gt;And I embarked on a &lt;a href=&quot;https://github.com/austenito/ruby-resty&quot;&gt;Ruby Port of Resty&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What started as a straight port, morphed into something I didn’t expect.&lt;/p&gt;

&lt;p&gt;I started a spike with my own REPL. Thinking more about features,
I realized I should be using something like the superb &lt;a href=&quot;https://github.com/pry/pry&quot;&gt;Pry&lt;/a&gt;. Pry allows Ruby Resty to be 
easily extensible with it’s &lt;a href=&quot;https://github.com/pry/pry/wiki/Custom-commands&quot;&gt;Custom Command&lt;/a&gt; infrastructure. Since we’re using plain ol’ Ruby,
we should use plain old ruby objects!&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;POST /api/nyan {&quot;name&quot;: &quot;grumpy&quot;} # JSON String
POST /api/nyan {name: &quot;grumpy&quot;}   # Ruby Hash
POST /api/nyan data               # User assigned variable in the REPL
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty nifty.&lt;/p&gt;

&lt;p&gt;One way Ruby Resty differs from Resty is host aliasing. Rather than specifiying a hostname, 
which maps to the config file, users can specify an easy to remember alias defined in ~/.ruby_resty.yml.&lt;/p&gt;

&lt;p&gt;This is still a working in progress and I would love some feedback. If you’re interested,
submit a &lt;a href=&quot;https://github.com/austenito/ruby-resty&quot;&gt;ruby-resty&lt;/a&gt; issue or reply to this post.&lt;/p&gt;


      </content>
    </entry>
  
    <entry>
      <id>http://growingdevs.com/welcome-to-growingdevs-com</id>
      <title>Welcome to Growing Devs</title>
      <link href="http://growingdevs.com/welcome-to-growingdevs-com.html" />
      <updated>2013-09-10T00:12:52+00:00</updated>
      <author>
        <name>Tony Pitale</name>
      </author>
      <content type="html">
        &lt;p&gt;Welcome to Growing Devs. This is a blog for a group of devs to share their
experiences – through writing and through code – in growing software,
themselves, and other developers. Or, just to write about any nerdy thing
we want to write about.&lt;/p&gt;

&lt;p&gt;The group is fluid. Some devs will write only once, and we hope that new devs
will join and write. All editorial review and publishing is handled through
GitHub pull requests.&lt;/p&gt;

&lt;p&gt;This is an experiment for us. But we think it has merit. In particular, we
think this format has the benefits of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;inspiring and challenging us to write&lt;/li&gt;
  &lt;li&gt;sharing the burden of editorial work&lt;/li&gt;
  &lt;li&gt;sharing success, recognition, and pagerank&lt;/li&gt;
  &lt;li&gt;not binding us to a single language, topic, or company&lt;/li&gt;
  &lt;li&gt;providing space to share content, without maintaining a solo blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can follow our &lt;a href=&quot;http://growingdevs.com/feed.xml&quot;&gt;RSS feed&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/growingdevs&quot;&gt;follow us
on Twitter @growingdevs&lt;/a&gt;, or we would love for you
to &lt;a href=&quot;https://github.com/growingdevs/growingdevs.github.io&quot;&gt;contribute&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The site is open source under the MIT license, all content is copyright of the
original authors and not of Growing Devs (which is not really an organization
of any kind anyway).&lt;/p&gt;

&lt;p&gt;Thanks for visiting, we look forward to sharing some new and wonderful content
in this experiment of ours!&lt;/p&gt;

&lt;p&gt;And again, if you would like to contribute a blog post you’ve had in the back
of your head for days or months, please feel encouraged to send us a pull
request.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
