My Little Blog

A blogging framework for hackers.

Deep Nested Attributes Using Has_many Through Join Model

(rails 3.2.15)

It’s been almost six months since I graduated from the Flatiron School. It’s hard to believe that I haven’t written a blog in just as long. Every time I overcame a challenge I kept telling myself that I should write a blog, but never got around to it.

But this. This problem was a tough nut to crack. I found hints of what to do on StackOverflow and countless articles, but three sources (appended at the end) were most useful. So, definitely check those out.

SCENARIO: My company had a very long and convoluted controller. The desire was to simplify it in anticipation for a version update. My task was to wipe the controller clean, redesign the corresponding section, and aim for simple CRUD. But I couldn’t get nested_attributes to work. So I broke the hash into pieces and wrote controller methods to get my CRUD actions to work in time for the release. It was shorter and cleaner than the previous version, and handled all validations beautifully. But it just seemed wrong to end up with a fat controller that doesn’t take advantage of the magic that is Rails (wink). I’ve sanitized the code a bit to keep it generic, but it works just the same.

Problems this blog addresses:

- Two-level deep nesting
- Parent-Child validation (Bi-Directional Association)
- Assigning multiple drop-down selections to nested object (Join Model Association)
- Multiple drop-downs from same collection: the last drop-down selection overwrites the first
- Join table with has_and_belongs_to_many association not working with nested_attributes
- Nested attributes works only on create action and not on update

VERSION 1: THE INITIAL CODE THAT DOESN’T AUTOMAGICALLY WORK

I setup my form using fields_for and accepts_nested_attributes_for following the Rails documentation. Here’s a high-level breakdown:

Car > Make > Pricing
           > Feature ( Select: #{feature_type_id: 1 } ) <-- Color
           > Feature ( Select: #{feature_type_id: 2)} ) <-- Body Type (2-door, 4-door...)

Here’s how controller and associations are originally setup in the models, and what the resulting hash looks like:

class CarsController < ApplicationController
  def new
    @car = Car.new
    make = @car.makes.build
    make.pricings.build
  end

  def create
    @car = Car.new(params[:car])
    if @car.save
      redirect_to edit_car_path(@car), notice: "Car created successfully"
    else
      redirect_to new_car_path(@car), notice: "Car could not be created"
    end
  end
end

Models
class Car < ActiveRecord::Base
  attr_accessible :name, :model_xx, :makes_attributes
  has_many :makes
  has_many :pricings,      through: :makes
  has_many :features,      through: :makes
  has_many :feature_types, through: :features
  accepts_nested_attributes_for :makes, allow_destroy: :true

class Make < ActiveRecord::Base
  attr_accessible :car_id, :vin, :pricings_attributes, :features_attributes
  belongs_to :car,           touch: true
  has_many   :pricings,      dependent: :destroy
  has_many   :feature_types, through: :features
  has_and_belongs_to_many :features, join_table: :features_makes
  accepts_nested_attributes_for :makes, allow_destroy: true

class Pricing < ActiveRecord::Base
  attr_accessible :make_id, :price, :currency
  belongs_to :make, touch: true
  has_and_belongs_to_many :makes, join_table: :pricings_makes
  validates  :make_id, :currency, :price, presence: true

class FeatureType < ActiveRecord::Base
  attr_accessible :name
  has_many  :features, dependent: :destroy
  validates :name,    presence: true
end

class Feature < ActiveRecord::Base
  attr_accessible :name, :feature_type_id
  belongs_to :feature_type
  has_and_belongs_to_many :makes, join_table: :features_makes
  validates :name, presence: true
end

form.haml
= form_for @car do |f|
  = f.label :car_name
  = f.text_field :name

  = f.label :model_code
  = f.text_field :model_xx

  = f.fields_for :makes do |v|
    = v.label :vin
    = v.text_field :vin

    = v.fields_for :features do |o|
      = o.label :id, "Color"
      = o.collection_select :id, Feature.where(feature_type_id: 1).order(:name), :id, :name, { prompt: "Select Color" }

      = o.label :id, "Body Type"
      = o.collection_select :id, Feature.where(feature_type_id: 2).order(:name), :id, :name, { prompt: "Select BodyType" }

    = v.fields_for :pricings do |p|
      = p.label :price
      = p.select :currency, Pricing.all.collect{ |p| [currency_symbol(p.currency), p.currency] }, { include_blank: "Currency" }, { class: "selectpicker", data: {style: "btn-primary currency-dropdown"} }
      = p.text_field :price

params:
"car"=>{"name"=>"delano", "model_code"=>"dx",
  "makes_attributes"=>{"0"=>{"vin"=>"vin98765",
    "pricings_attributes"=>{"0"=>{"currency"=>"usd", "price"=>"100000"}},
    "features_attributes"=> {"0"=>{"id"=>"6"}, "1"=>{"id"=>"4"}}
  }}
}

In a perfect world, clicking submit triggers Car.create(params[:car]) and the car auto-magically creates not only itself, but also all of its makes and associations in one fell swoop.

In reality, the car cannot be created for a number of reasons:

- Car and Make cannot be saved simultaneously because:
  - Car is not valid because there's no make_id
  - Make is not valid because there's no car_id
  - Pricing is not valid because there's no make_id
- Make doesn't know what to do with the features hash
- Last feature selection over-writes the first selection

BI-DIRECTIONAL ASSOCIATION: Parent-Child Validation for Nested Attributes

What’s causing this error:

ActiveRecord::RecordNotFound: Couldn't find [table] with ID=1 for ... with ID=

By default, Active Record (AR) creates separate in-memory copies of object data. You need to specify to Rails that there’s an inverse relationship between models to optimize object loading. If you don’t, AR creates objects with no association to each other. By specifying an inverse relationship, you’re telling AR that this Pricing belongs to this make, which belongs to this car. In addition to telling AR how to load the objects, you also need to set the :autosave feature to tell it that you want to save the members simultaneously. By default this is set to false.

You should also set validations down the line to require each object and specify any dependencies that need to be destroyed along with the parent (unless you want orphaned objects littering your database). Finally, you should add a variant hidden field if you forgot to include it earlier. This facilitates bi-directional relationships through the variant.

class Car < ActiveRecord::Base
  ...
  has_many  :makes, inverse_of: :car, autosave: true, dependent: :destroy
  validates :makes, presence: true
  accepts_nested_attributes_for :makes, allow_destroy: :true, reject_if: :all_blank
  ...
end

class Make < ActiveRecord::Base
  ...
  has_many  :pricings, inverse_of: :make, autosave: true, dependent: :destroy
  validates :car,      presence: true
  accepts_nested_attributes_for :features, :pricings, allow_destroy: true
  ...
end

class Pricing < ActiveRecord::Base
  ...
  validates :make, presence: true
  ...
end

form.haml
= form_for @car do |f|
  ...
  = f.fields_for :makes do |v|
    = v.hidden_field :id

ASSIGNING DROP-DOWN SELECTIONS TO NESTED ATTRIBUTE VIA JOIN TABLE

This is a complex issue because not only are we trying to assign two sub-sets of the same collection (color and body-type) per make, but we’re attempting to do it through a join table.

What’s causing this error:

[...]Controller# (ActionView::Template::Error) "Unknown primary key for [table] in model [...]"

The reason has_many :through associations allow you to do all sorts of things through join tables that you wouldn’t ordinarily be able to with HABTM (such as callbacks and validations), is because there’s a primary key to reference each joined record. If all you’re doing is joining tables and don’t need any special behavior, then it’s quickest to use HABTM and create a join table. That’s what we had, but we needed more.

JOIN MODEL ASSOCIATION: Using has_many :through on a join table

Since we are assigning features before a make_id exists, has_many associations to the join table need to be written so as to allow parent-child validation through bi-directional association. This is done following the same logic as employed in the previous example.

Note that Rails needs a primary key to manage has_many :through associations on join tables. Since my join table already exists, I run a migration to add a primary key to the join table and use first: true to make it the first column. Finally, I update my form builder and nested_attributes on my form to reflect the association to the join table.

Notice that the feature value for each drop-down is simultaneously built along with the join record. Instantiating one of each FeatureType when building the form: (a) takes care of the last drop-down over-writing the first, and (b) gives us a handy new join record to link through to each of our features.

class AddIdToFeaturesMakes < ActiveRecord::Migration
  def change
    add_column :features_makes, :id, :primary_key, first: true
  end
end

class Make < ActiveRecord::Base
  ...
  has_many :features,       through: :features_makes, source: :feature
  has_many :features_makes, inverse_of: :make, autosave: true, dependent: :destroy
  ...
end

class FeaturesMakes < ActiveRecord::Base
  attr_accessible :make_id, :feature_id, :feature_attributes
  belongs_to :make
  belongs_to :feature
  validates  :make, :feature, presence: true
end

class Feature < ActiveRecord::Base
  ...
  has_many :makes,          through: :features_makes
  has_many :features_makes, inverse_of: :feature, autosave: true, dependent: :destroy
  ...
end

CarsController.rb
def new
  @car = Car.new
  make = @car.makes.build
  make.pricings.build
  2.times { |n| make.features_makes.build.build_feature(feature_type_id: n+1) }
end

form.haml
= v.fields_for :features_makes do |ov|
  - features = ::Feature.where(feature_type_id: ov.object.feature.feature_type_id)
  = ov.label :feature_id, "#{ov.object.feature.feature_type.name}"
  = ov.collection_select "feature_id", features.order(:name), :id, :name, { prompt: "Select #{ov.object.feature.feature_type.name}" }, { class: "selectpicker select-block", data: {style: "btn-primary"} }

Why do nested attributes work on #create but not on #update?

If for any reason you decide to leave the primary key out, it is absolutely possible to assign feature values to a new make. Through trial and error – trying to get this to work – I discovered that you can use has_many :through without adding a primary key. You can tell Rails what primary key you want it to use, which can be an array (or composite):

class Featuresmake < ActiveRecord::Base
  attr_accessible :make_id, :feature_id, :feature_attributes
  self.primary_key = [:make_id, :feature_id] <-- [ Setting primary key on a join table ]
  ...
end

But – while possible – what’s the point? It’s a waste of real estate AND you don’t get the full benefit that you get with a primary key. The biggest impediment is that you won’t be able to update drop-down selections. Instead you’ll end up with two new drop-downs anytime you try to update color or body-type for an existing make. The reason for this is that Rails will instantiate a new record when it can’t find a primary key. So, there you go.

FINAL VERSION: THE CODE THAT AUTOMAGICALLY WORKS

JOIN MODEL ASSOCIATION: Add primary key to join table

class AddIdToFeaturesmakes < ActiveRecord::Migration
  def change
    add_column :features_makes, :id, :primary_key, first: true
  end
end

FORM BUILDER: Build instances for desired associations

CarsController.new
def new
  @car = Car.new
  make = @car.makes.build
  make.pricings.build
  2.times { |n| make.features_makes.build.build_feature(feature_type_id: n+1) }
end

BI-DIRECTIONAL ASSOCIATION: Specify parent-child relationship

class Car < ActiveRecord::Base
  attr_accessible :model, :description, :model_code, :makes_attributes
  has_many  :makes,          inverse_of: :car, autosave: true, dependent: :destroy
  has_many  :feature_types,  through: :features
  has_many  :features,       through: :makes
  has_many  :pricings,       through: :makes
  validates :makes,          presence: true <--[ Validates presence of inverse_of object ]
  accepts_nested_attributes_for :makes, allow_destroy: :true, reject_if: :all_blank
  (...)
end

class Make < ActiveRecord::Base
  attr_accessible :name, :car_id, :model_code, :pricings_attributes, :features_attributes
  belongs_to :car,          touch: true
  has_many :pricings,       inverse_of: :make, autosave: true, dependent: :destroy
  has_many :features_makes, inverse_of: :make, autosave: true, dependent: :destroy
  has_many :images,         through: :features
  has_many :feature_types,  through: :features
  has_many :features,       through: :features_makes, source: :feature ### replaces habtm
  validates :car,           presence: true <--[ Validates presence of inverse_of object ]
  accepts_nested_attributes_for :features_makes, :pricings, allow_destroy: true
  (...)
end

class Pricing < ActiveRecord::Base
  attr_accessible :make_id, :currency, :price
  belongs_to :make,     touch: true
  validates  :make,     presence: true <--[ Validates presence of inverse_of object ]
  validates  :currency, presence: true
  (...)
end

class FeatureType < ActiveRecord::Base
  attr_accessible :name
  has_many  :features, dependent: :destroy
  validates :name, presence: true
end

class Feature < ActiveRecord::Base
  attr_accessible :name, :presentation, :feature_type_id
  belongs_to :feature_type
  has_many   :features_makes, inverse_of: :feature, autosave: true, dependent: :destroy
  has_many   :makes,          through: :features_makes
  validates  :name,           presence: true 
  (...)
end

class FeaturesMakes < ActiveRecord::Base
  attr_accessible :make_id, :feature_id, :feature_attributes
  belongs_to :make
  belongs_to :feature
  validates  :make, :feature, presence: true <--[ Validates presence of inverse_of object ]
end

INPUT FORM

form.haml
= form_for @car do |f|
  = f.label :car_model
  = f.text_field :model

  = f.label :model_code
  = f.text_field :model_code

  = f.fields_for :makes do |v|
    = v.hidden_field :id

    = v.label :vin
    = v.text_field :vin

    = v.fields_for :features_makes do |ov|
      - features = ::Feature.where(feature_type_id: ov.object.feature.feature_type_id)
      = ov.label :feature_id, "#{ov.object.feature.feature_type.name}"
      = ov.collection_select "feature_id", features.order(:name), :id, :name, { prompt: "Select #{ov.object.feature.feature_type.name}" }, { class: "selectpicker select-block", data: {style: "btn-primary"} }

    = v.fields_for :pricings do |p|
      = p.label :price
      = p.select :currency, Pricing.all.collect{ |p| [currency_symbol(p.currency), p.currency] }, { include_blank: "Currency" }, { class: "selectpicker", data: {style: "btn-primary currency-dropdown"} }
      = p.text_field :price

PARAMS

"car"=>{"name"=>"delano", "model_code"=>"dx",
  "makes_attributes"=>{"0"=>{"vin"=>"vin98765", 
    "features_makes_attributes"=>{"0"=>{"feature_id"=>"6"}, "1"=>{"feature_id"=>"4"}}, 
    "pricings_attributes"=>{"0"=>{"currency"=>"usd", "price"=>"100000"}}}}}

Sources:
http://robots.thoughtbot.com/accepts-nested-attributes-for-with-has-many-through http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html http://www.sitepoint.com/complex-rails-forms-with-nested-attributes

Ruby & Me: Include vs Other Includes

The beautiful thing about ruby is that it wants to be expressive and legible – it aims to mimic human language. Unfortunately human language is not that consistent. Words are not used the same way all the time because usage is often driven by context. The good news is that Ruby makes some allowances for this and provides different ways (aka methods) to help us be more explicit in our programming.

For example, ‘map’ is a method that performs the same job as ‘collect’, and there are times when you might find it preferable to specify that values are being collected from a block vs. when they are being mapped. The truth is though that ‘map’ has been historically used in functional programming, and might sometimes be used to please the habitual self over semantic purpose.

So there we have it. Po-TAY-toh Po-TAH-toh… but this is America and we say Po-TAY-toh! Seriously though, it’s best to use whatever language helps you and others easily read your code. But what happens when terms are the same, or overlap between Ruby and Rails?

I was recently asked to explain what include does in Rails, and the first thing that came to mind was the ruby method include?(obj) – a boolean method that returns true if the given object is present in self:

grades = ["A", "C+", "B-"]
grades.include?("A") #=> true
grades.include?("F") #=> false

But ‘include?’‘ is a ruby method, and the question specified Rails. Hm. Well, I’ve used ‘include’ in Ruby to mix in module instance methods, but I simply haven’t had to use it in Rails. So later in the day I did what any self-respecting nerd would do, and looked its usage up in RailsGuide. I also asked my classmates and instructor the same question. Sample responses included: like where in Rails? in a mixin? a module? in eager loading? what do you mean?

As Tony the Tiger says: grrreat.

This post briefly explores the various uses of a similarly named method between Ruby (1.9.3) and Rails (3.2.13), using the variations of “include” as an example. The include method is not by any means the most exciting one, but it is one that is commonly used in different contexts.

In Ruby, many methods such as include? can be similarly applied to various contexts with slight variations:

array.include?(true_if_this_object_is_present_in_array)
  [1,2,3,4].include?(2) #=> true
  [1,2,3,4].include?(5) #=> false

hash.include?(true_if_this_key_is_present_in_hash)
  {:name => "Bob", :age => 25}.include?(:name) #=> true
  {:name => "Bob", :age => 25}.include?(:gender) #=> false

"string".include?(true_if_this_string_or_character_is_present_in_string)
  "hello".include?("el") #=> true
  "hello".include?("pi") #=> false

(range "this".."that").include?(true_if_this_object_is_an_element_of_range)
  (34..76).include?(38) #=> true
  (34..76).include?(14) #=> false

environment_variable.include?(true_if_there_is_an_environment_variable_with_this_name)
  PATH = "/Users/LittleApple/.rvm/gems/ruby-1.9.3-p429/bin"
  ENV['PATH'].include?('bin') #=> true
  ENV['PATH'].include?('BigApple') #=> false

module.include?(true_if_this_module_is_present_in_the_module_or_one_of_the_module's_ancestors)
  module Granny
  end

  class Mama
    include Granny
  end

  class Baby < Mama
  end

  Mama.include?(Granny)   #=> true
  Baby.include?(Granny)   #=> true
  Granny.include?(Granny) #=> false

There are Public Class methods, Private Class methods, Module methods, Enumerable methods, and so on. This leads to some additional variations on the usage of ‘include’ in Ruby:

Module.include(module, ...) 
  #=> used to mix module constants, methods, and variables into the Module or class instances.

Module.included_modules 
  #=> returns an array list of modules that are included in Module.

Module.included(other_module)
  Module Hello
    def Hello.included(other_module)
      (...) 
    end
  end

  Module
    include Hello
  end
  #=> callback is invoked when the (receiver) is included in another module or class. 

Moving onto Rails.

ActiveRecord in Rails is an object relational mapping system that lets you retrieve objects from your database using queries that execute as SQL, without actually having to write raw SQL. Includes is one of the many finder methods available in ActiveRecord that helps minimize the number of queries run against your database.

With the includes method, all associations can be specified in advance by passing arguments. This act of preloading is also known as eager loading, and is how ActiveRecord tackles N+1 – a problem that occurs with associations. When you load the parent object and start loading one child or association at a time, you end up having to run N+1 queries. Pre-loading associations minimizes the number of queries by way of its specificity:

School.includes("students").where(first_name: 'Ryan', students: {status: 'accepted'}).count

The includes method can come in handy when you want to display the same information in multiple views but don’t want to bog down performance by repeatedly running the same query. To provide even more flexibility, Rails has an :include option for those times that a different finder method might be better suited to your query, but you still want to eager load associations.

Since Rails runs on the Ruby programming language, the various ‘include’ ruby class and module methods can be used to respectively drive object behavior or refer to modules, mix-ins or concerns.

So there you have it. The many wonderful uses of the term ‘include’.

Ruby & Me: Converting Roman Numerals to Arabic

Yesterday was a big day. I graduated from the FlatironSchool 12-week program (yay! applause).

It’s been an intense race to pack in as much knowledge as possible in a short time-frame. As a parting gift, we were given an appropriate signifier that we are now versatile web application developers: a swiss army knife.

In recent weeks, it’s been difficult not to notice time ticking away against our task list:
– Absorb knowledge
– Complete web application for ScienceFair
– Absorb knowledge
– Practice ruby problems in preparation for Interviews
– Absorb knowledge
– Ask for 11th-hour lectures to make sure we understand topic xyz
– Absorb knowledge

In the end, as a coping mechanism, my peers and I decided that it was best to look at graduation not as the end of the road but as a new beginning. I’m happy to say that I’ve made it through the program. I’m also happy to report that I’ve largely absorbed most of my newfound knowledge.

The harrowing schedule has made it difficult for many of us to keep up with our blogs, but I’m ready and raring to go. So, I’ve decided to start a new segment called ‘Ruby & Me’ to a) force me to review my notes, b) test my understanding of basic concepts, and c) document my thought process as I work through problems. The immediate result may not be pretty, but this is what the result looks like short of refactoring. In the words of our Dean, Avi Flombaum: Make it work – Make it right – Make it fast. Then and only then: refactor.

Problem: Convert roman numerals to arabic

I’ve learned the hard way that it’s paralyzing to look too far ahead. Small successes are productive and feel great. So, I start with the following pseudo-code:

# Convert roman numerals to arabic:
# I, V, X, L, C, D, M
# NumTranslator.new("V") return arabic numeral value 5

My first goal is to create a class in which I can instantiate a new object and successfully pass my roman numeral between methods. By the way, I’ve also learned the hard way that too much coding without testing is a recipe for disaster. The last thing I want is to get bogged down debugging my code, but I’ve done it before… a lot. So, let’s see how this works out:

class NumTranslator
  def initialize(roman_numeral)
    @numeral = roman_numeral
  end

  def translator
    @numeral = "V" 
  end
end
puts NumTranslator.new("V").translator

return value #=> V

My first test passes. Awesome! Now I want to setup a simple translator that deals with all single-digit roman numerals:

def translator
    case @numeral
    when "I" then 1
    when "V" then 5
    when "X" then 10
    when "L" then 50
    when "C" then 100
    when "D" then 500
    when "M" then 1000
    else
    puts "Please enter a roman numeral"
  end 
end
puts NumTranslator.new("V").translator

return value #=> 5

Second test passes. Cool. Now I want to make sure that my full translation table works so I modify my call to accept user input:

puts "Enter roman numeral to convert to arabic numeral: "
print NumTranslator.new(gets.chomp).translator

At this point I realize that I should probably help guard my entries from my lightning fingers.

def initialize(roman_numeral)
  @numeral = roman_numeral.upcase
end

Sweet, now I can mistakenly enter a lowercase letter and it will automatically be upcased.

Now comes the tough part. Translation is easy at a single digit level, but if I enter a multiple digit roman numeral, I get the following response: “Please enter a roman numeral”. It’s time to alter my method so that I can deal with multiple letter roman numerals. I know that adjacent numerals sum to a total value e.g. “III” = 3. I also know that there are exceptions but I choose to ignore those for now.

Since each digit within a roman numeral translates to a value, I decide to update my translator method to split the input string and see if I can get “III” to return 3. I decide to use the collect method because I want to add each letter to an array. This will allow me to iterate through and add up all the values.

def translator
  @numeral = @numeral.split('').collect do |letter|
    case letter
    when "I" then 1
    when "V" then 5
    when "X" then 10
    when "L" then 50
    when "C" then 100
    when "D" then 500
    when "M" then 1000
    else
      puts "Please enter a roman numeral"
    end
  end
  @numeral.inject(:+)
end

(...)

gets.chomp #=> "III"
return value #=> 3

Excellent! It works. It’s time to get happy:

gets.chomp #=> "XI"
return value #=> 11

Yippee!

gets.chomp #=> "LV"
return value #=> 55

Hoorah!

gets.chomp #=> "XX"
return value #=> 20

Woopdeedoo!

gets.chomp #=> "IV"
return value #=> 6

Sigh. Ok, enough prolonging the inevitable. Good thing I’ve learned to manipulate my expectations: Yay! Yay! Yay! Waaaah!

Time for more pseudo-code:

# Translator method assumes each single-digit character is unique
# It splits and translates each character into a number, and adds it to an array
# Exceptions must be converted to a single-digit string and added back to the roman numeral
# Exceptions: "IV" = "4" / "IX" = "9" / "XL" = "F" (forty) / "XC" = "N" (ninety)

The translator method is already crazy long, so it seems appropriate to create a separate method to detect exceptions. I decide to start with “IV” and “IX” to keep things simple.

def detect_exception
  if @numeral.include?("IV")
    @numeral = @numeral.split("IV").push("4").inject(:+)
  elsif @numeral.include?("IX")
    @numeral = @numeral.split("IX").push("9").inject(:+)
  else
    @numeral
  end
end

Let’s test this real quick:

puts "Enter roman numeral to convert to arabic numeral: "
print NumTranslator.new(gets.chomp).detect_exception

gets.chomp #=> "XXIV"
return value #=> "XX4"

Cool, that works.

puts "Enter roman numeral to convert to arabic numeral: "
print NumTranslator.new(gets.chomp).detect_exception

gets.chomp #=> "LXIX"
return value #=> "LX9"

Awesome. Now I need to figure out how to expand this to include the other exceptions. I find that I can’t just add these as additional elsif statements because there seems to be confusion with overlapping numerals, so I try to nest them:

def detect_exception
    if @numeral.include?("IV")
      @numeral = @numeral.split("IV").push("4").inject(:+)
      if @numeral.include?("XL")
      @numeral = @numeral.split("XL").push("F").inject(:+)
      elsif @numeral.include?("XC")
      @numeral = @numeral.split("XC").push("N").inject(:+)
      else
      @numeral
      end
    elsif @numeral.include?("IX")
      @numeral = @numeral.split("IX").push("9").inject(:+)
      if @numeral.include?("XL")
      @numeral = @numeral.split("XL").push("F").inject(:+)
      elsif @numeral.include?("XC")
      @numeral = @numeral.split("XC").push("N").inject(:+)
      else
      @numeral
      end
    elsif @numeral.include?("XL")
      @numeral = @numeral.split("XL").push("F").inject(:+)
      elsif @numeral.include?("XC")
      @numeral = @numeral.split("XC").push("N").inject(:+)
    else
      @numeral
    end
  end

It’s butt ugly, but it works. Only a single line needs to be added to the translator method to call this new method to detect exceptions:

def translator
  @numeral = self.detect_exception
  @numeral = @numeral.split('').collect do |letter|
  (...)
  end
end

Excellent. Now we just need to test that everything works:

puts "Enter roman numeral to convert to arabic numeral: "
print NumTranslator.new(gets.chomp).translator

gets.chomp #=> "MMMDXCLXIX"
return value #=> "3669"

I can hardly contain myself. I run about fifteen different number combinations to make sure that everything works. Sweet! Hopefully, I didn’t leave out any exceptions.

UPDATE: Special thanks to Ed for pointing out a problem with my nested conditions under detect_exception, and for suggesting saving on real estate by using a hashmap instead of a case statement.

Here’s the final code:

class NumTranslator

  def initialize(roman_numeral)
    @numeral = roman_numeral.upcase
  end

  def detect_exception
    if @numeral.include?("IV")
      @numeral = @numeral.split("IV").push("4").inject(:+)
      if @numeral.include?("XL")
      @numeral = @numeral.split("XL").push("F").inject(:+)
      elsif @numeral.include?("XC")
      @numeral = @numeral.split("XC").push("N").inject(:+)
      else
      @numeral
      end
    elsif @numeral.include?("IX")
      @numeral = @numeral.split("IX").push("9").inject(:+)
      if @numeral.include?("XL")
      @numeral = @numeral.split("XL").push("F").inject(:+)
      elsif @numeral.include?("XC")
      @numeral = @numeral.split("XC").push("N").inject(:+)
      else
      @numeral
      end
    elsif @numeral.include?("XL")
      @numeral = @numeral.split("XL").push("F").inject(:+)
      elsif @numeral.include?("XC")
      @numeral = @numeral.split("XC").push("N").inject(:+)
    else
      @numeral
    end
  end

  def translator
    hashmap = {"I"=>1,"4"=>4,"V"=>5,"9"=>9,"X"=>10,"F"=>40,"L"=>50,"N"=>90,"C"=>100,"D"=>500,"M"=>1000}
    @numeral = self.detect_exception
    @numeral = @numeral.split('').collect do |numeral|
      hashmap[numeral]
    end
    @numeral.inject(:+)  
  end
end
puts "Enter roman numeral to convert to arabic numeral: "
puts NumTranslator.new(gets.chomp).translator

Rails Deployment to Digital Ocean Ubuntu via Capistrano

We are in the 11th week of Flatiron School. It has been a whirlwind of learning, and it feels great to finally deploy our first Rails app today. Deployment was painful, so I’m posting this walk-through in hopes that it might save someone some deployment time. My team started this process with high hopes of crushing it in 45 minutes. Instead we ran into all sorts of annoying problems to debug for the next 3 hours (ugh!).

Some hurdles that were overcome and that are discussed in this post are: asset pre-compilation errors, Sunspot solr gem headaches, Database not seeding, and image_tag ‘isn’t precompiled’ error message.

This walk-through builds on an excellent tutorial by guest speaker Spike Grobstein. My intent is not to plagiarize any of that work, but instead to add in some steps that were needed for me to get our application deployed and working.

We were provided the following information by our TA Blake: (a) Digital Ocean droplet to serve our app, and (b) credentials (IP Address / Username: root / Password). He then sent us packing to work on our own because he’s a meanie (just kidding). One skill you’ll sharpen while in this program is your ability to walk in the dark. Not to worry though. There is light to be found for those who persevere. Anyway, I digress.

Before you start anything you’ll want to make sure that all working git branches are up-to-date, reviewed, merged and pushed up to master accordingly. This may not be a big concern if you’re working solo, but a critical step for our team of four sharing workload.

Open terminal, cd into your Rails app and let’s get ready to rumble.

PHASE 1: Connect to your spankin’ new server
In the code base a hashtag # represents a comment, so don’t type it – ok?

Connect to your new server via SSH:

ssh root@XXX.XXX.XXX.XXX # plug your IP address in the place of the X's

Answer questions politely:

Are you sure you want to continue connecting (yes/no)? # type yes and press enter

Root is a super user, so you should really create a user for the app since it brings bad mojo on top of 7 years of bad luck to do otherwise – it’s bad practice, so don’t be that person:

useradd -s /bin/bash -G sudo -m outlinked # note: our app is called "outlinked", enter username.

Then you have to create a password for this user, but you won’t be entering the password right away. You’re going to tell the server which username you want to apply the password to:

passwd outlinked

When prompted for a password, choose one and confirm it.

Groovy, now exit the server and connect as your alter-ego (aka your new username):

ssh outlinked@XXX.XXX.XXX.XXX # you know what to do with these X's now

Enter your password, and get ready to install the packages your app will need to run on your Ubuntu server.

PHASE 2: Get your server ready for your awesome application

Update your apt-repository and dependencies with this code:

sudo apt-get update

Then upgrade all installed packages with this code:

sudo apt-get upgrade

You’ll be shown a list of packages that need upgrading, and then asked to confirm. Be polite and answer in the affirmative:

Y # press enter

Install build essential package:

sudo apt-get install build-essential

Install Ruby packages:

sudo apt-get install ruby1.9.3 sqlite3 libsqlite3-ruby1.9.1 libsqlite3-dev

Install Git:

sudo apt-get install git

Install XML libraries (this one is for gems using the stated libs e.g. Nokogiri):

sudo apt-get install libxml2-dev libxslt1-dev

Install Gem Bundler:

sudo gem install bundler

Install SQLite3:

sudo gem install sqlite3

Install nodejs (avoids compile errors with the Javascript framework):

sudo apt-get install nodejs

Install Capistrano, which you’ll be using to deploy your app:

gem install capistrano

Install Passenger, which is an nginx module and your Rack webserver:

sudo gem install passenger
sudo passenger-install-nginx-module
sudo apt-get install libcurl4-openssl-dev libssl-dev zlib1g-dev
sudo nano /opt/nginx/conf/nginx.conf # configure nginx
# scroll through the nano file looking for #user  nobody;
# uncomment that, and change nobody; to www-data;
# keep scrolling and find the location block now
# Replace the whole block:
  location / {
   root   html;
  index  index.html index.htm;
  }
# with:
  root /home/USERNAME/APPNAME/current/public;
  passenger_enabled on;
# Exit the editor (Ctrl + X)
sudo ln -s /opt/nginx/sbin/nginx /usr/local/sbin/
sudo nginx # Start nginx
(To stop ngingx: sudo nginx -s stop)

Congratulations, you’re well on your way to making your app dreams a reality!

PHASE 3: Application config files & Deployment

Go ahead an open a new terminal tab so that you can cd back into your application’s repo on your local drive. All Capistrano needs for you to type in the command line to start the deployment process is:

capify .

Excellent, let’s update a few settings in our application to enable deployment.

Navigate to the config directory, open deploy.rb and edit it as follows:

set :application, "outlinked" # Set application to USERNAME

# Enter your github ssh handle (the https one didn't work for us)
set :repository,  "git@github.com:flatiron-school/library-redux.git"

set :user, 'outlinked' # Set user to USERNAME

set :deploy_to, "/home/outlinked/outlinked" # Set deploy_to to /home/USERNAME/APPLICATION

set :user_sudo, false

set :rails_env, "production" # sets your server environment to Production mode

set :scm, :git  # sets version control

default_run_options[:pty] = true

role :web, "XXX.XXX.XXX.XXX" # Your HTTP server, Apache/etc
role :app, "XXX.XXX.XXX.XXX" # We made the app role the same as our `Web` server 

# We made the database role the same as our our `Web` server 
role :db,  "XXX.XXX.XXX.XXX", :primary => true # This is where Rails migrations will run

# We're using Passenger mod_rails, so we uncommented this:
namespace :deploy do
  task :start do ; end
  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
  end
end

Cool. We’re getting closer to the promise land.

Now go into your Capfile in your application, and uncomment the following:

load 'deploy/assets' # this will precompile your assets every time you deploy

Oh yeah, don’t forget to add and commit your changes:

git add .
git commit -am "edit deploy.rb"
git push

My team had to generate a deploy key because our application sits in a private Github repo. If this doesn’t apply to you, keep reading because one day you’ll need to do this. Switch your terminal tab so that you’re back into your server command line and enter this code:

ssh-keygen -t rsa -b 4096 # Leave all requests for passwords blank! 
                          # Hit enter until no more questions are asked.

Now you’ll need to open your browser and navigate to your repo in Github. Click on ‘Settings’ and then on ‘Deploy key’, and then finally on ‘Add deploy key’. Enter your github password, and go back to your server terminal to retrieve the key to copy/paste into github:

cat ~/.ssh/id_rsa.pub # copy everything from the ssh-rsa to username@host.
                      # I first opened this file with nano, which only showed a partial key.
                      # Don't enter a title for the key. Github will use your username.

Awesome. Now jump back into your other terminal window where you’re in your local repo and run:

cap deploy:setup

This connects you to your server, prompts you for your password and creates your directory structure on the server. When you cd into your USERNAME directory in your server, you’ll see three sub-directories: current, releases and shared. The current directory is the server equivalent of your application directory in your local directory.

I should mention that a log folder wasn’t immediately available in the current directory. This became an issue when I ran into a problem deploying and I couldn’t get to my production.log to review error messages. I got help from our TA Joe for this, and there was some light-fingered magic going on, so I don’t have exact code to post. My understanding is that the Production.log file in the current directory points via symlink to a log file in the shared directory, which did not exist. You can check this status by doing an ls -l and looking for line items in red.

Guess what? It’s time to deploy – Heck yeah!
So you’ve done like a million steps already and we’re just deploying now. Pat yourself on the back and give yourself a high five.

All your changes are committed, right? Cool. You’re ready to deploy. From your local repo terminal, enter the magical Capistrano command while singing O Sole Mio:

cap deploy

Open your browser, type in your IP address in the url bar http://[your IP]

Celebration time, right? Wrong. This is where error messages plagued me.

Important note: you know all that stuff you have to do in your local Rails app like bundle install and all that jazz? That doesn’t magically happen in the server. All the routines required in your local drive, you’re going to have to repeat here.

Problem no. 1 – Sunspot gem We installed this gem so that users can run searches in our app. This gem was a pain in the ass from day one. It runs a Java server and it’s been a challenge to update every time we changed seats during pair programming. A good rule of thumb is that whatever you’ve had to do to fix problems in your local drive, you’ll likely have to repeat in your server environment. For one you have to install a Java environment:

sudo apt-get install openjdk-6-jdk

Next you’ll need to cd into your app USERNAME/current and do all that other junk that fixes rake errors:

rails g sunspot_rails:install RAILS_ENV='production'
rake sunspot:solr:start RAILS_ENV='production'
rake sunspot:reindex RAILS_ENV='production'

The reason I’m tacking on RAILS_ENV=‘production’ at the end of each rake command is that I haven’t set up rake tasks in my config file in Rails to default to production mode. I figured this out after numerous failed attempts at seeding. According to my rails console the data was seeding, but it turns out the simple rake command populates the development database and not the production one. Did you know that typing rails c in the server gets you the development database and rails c production gets you the production database? Holy batman, it’s a thing! Lesson learned after beating my head against the wall for about an hour.

Time to setup the tables and seed the files:

bundle exec rake db:seed RAILS_ENV='production'
rake db:migrate RAILS_ENV='production'

Restart the server now by typing:

touch tmp/restart.txt # if you get a permissions error: sudo touch tmp/restart.txt

Reload your browser and voilà! Did it work? For me it still didn’t!

Merde! Pardon my french, but this is wholly aggravating by this time. Thank goodness for TA Ashley for helping me retain my sanity.

Here’s the error message I was getting:

ActionView::Template::Error ( isn't precompiled):
    17: (...)
    20:   <%= image_tag("#{topic_link.link.user.image}", size: "25x25") %>

I was stuck on this Mo-Fo for at least an hour because every new person that swooped in concluded that it was a pre-compiling error. So round and round in circles I went. It turns out that this is a legit Rails issue that was brought up on github/Rails. Thank you Ashley, I’m not a complete dope! The story here is this:

My team didn’t set a default image for avatars. Instead we just had an erb link in line 20. When there is no image available, there’s a nil in this field. This was no big deal in development in our local drive, but in Production mode: no-likey. So we tried to put ‘if statements’ to by-pass the error, but it didn’t like that either. Long story short, we deleted the line in the short-term so that we could complete deployment. Tomorrow, I’ll add a default image to my assets, which we can link to if image is nil.

In the meantime? Success is sweet!

Argh Matey: Connecting the Dots in Rails

It’s been a crazy 5 weeks at the Flatiron School, but things are finally starting to click – thanks in part to our instructors patiently walking us through a number of examples. While this post might seem trivial to some readers, bear in mind that 5 weeks ago I had TextWrangler installed on my laptop. Ew. I know, like, for realz AND I was practicing stuff like var = x.

Anyway, fast forward to the future: the one exercise that resonated with me was one relating Pirates and Ships. It helped me understand Ruby at a time that I hit a seemingly bottomless pit of ‘why the heck don’t I get this stuff?’ desperation. Plus, it kept me entertained since every sentence invariably ended up with an “argh matey” in my head.

The good news is that after a few weeks of Ruby and a week of Sinatra, we’ve started to delve into Rails. One benefit of learning Sinatra first is that you realize how magical Rails is. Holy Shit it does WHAT for you? Everything?! You just wave your magic wand and friggin’ wha?! Ladies and Gentlemen [drumroll] et voilà [poof] ze app extraordinaire! [applause]

Not exactly.

The bad news is, we had homework due in which we were asked to populate a database and create a simple app based on a previous Sinatra application. How hard could that be? I mean Rails is freakin’ magic after all. Ok, well maybe we also had to scrape data off a website first before.

So (staring down at my laptop) my first question is how do I get data in this thing? At this point, I should mention that until recently, accessing and entering data has been something of a mystery to me. Everyone’s debugging and doing params stuff while I can’t seem to select the right command in irb that does anything useful – driving blind at 150mph. Classic. We’ll come back to that.

The first thing to grasp about Rails is that the framework is composed of three primary components the: Model, View and Controller. Note that the Model talks to the database using some Rails voodoo called ActiveRecord. I like this handy-dandy diagram because it shows you how the database interacts with the framework. But I hate this image because it confuses my thinking of where to enter my code so that it automagically pulls my data into the database.

No worries. There must be some guide that explicitly states how to get your data in, so that you can figuratively link your model, views and controller right? Wrong. Someone tell me why there isn’t such as resource within the top 3 search results! I’ll tell you why… like duh, you just setup your models, and then your controller is a basic ruby class and then all you have to do is just populate your database and test it in your views. And if you’re having trouble with the data, you just throw in pry-debugger or raise params. Capisce? [blank stare] No.

The first time I used Rails, I peeked into every folder trying to figure out the appropriate place for my database (see my Sublime sidebar below left). Now that I look at it, I feel like I should have been like: “Duh, what about the db directory?”

Let me break down my quandary for you. There are plenty search results for ‘Rails database’ but the best answers show individual chunks of code without stating where it belongs. Some people talk about creating a controller and a model, others create just a model, there are examples on how to create a rake task in the lib directory, and others still enter their code in a seeds.rb file in the db directory. Everyone online has an opinion, and everyone’s an expert.

BUT if you just want to play around with Rails to get a hang of it, here’s how I recommend you get started once you’ve installed Rails.

Step 1 – Create a new rake application and cd into your application:

> rails new pirates-rails-app

Step 2 – Create two Models (notice that Model title names are always singular):

> rails generate model Ship name:string pirate_id:integer

Follow the Rails convention of naming your components properly if you want your app to work properly. In this example we use column name and type, but you could omit this piece [name:string pirate_id:integer] and add whatever columns you like later.

You should have two new ruby class files in the Model directory.

class Pirate < ActiveRecord::Base
   attr_accessible :location, :name
end    

class Ship < ActiveRecord::Base
   attr_accessible :name, :pirate_id
end

Step 3 – Enter some data to play with in the seed.rb file, which is in the db directory:

ships = Ship.create([{ name: 'Queen Anne\'s Revenge', pirate_id: 1}, {name: 'Barnacle', pirate_id: 2}])
pirates = Pirate.create([{ location: 'West Indies', name: 'Blackbeard'}, { location: 'Rumrunner Isle', name: 'JackSparrow' }])

Enter ‘rails console’ in the command line to launch Rails irb console. If you can get your data to pass muster here, it should work in the seeds file. This won’t work until you run a ‘rake db:migrate’ to migrate your data into the database. Hold off on this for a little while.

Step 4 – The easiest way to create a Controller is to generate a scaffold. You’ll probably hear all sorts of reasons why you should shun scaffolds, but it’s a great way to see how things connect:

> rails generate scaffold Ship
> rails generate scaffold Pirate

Don’t just accept this. Look at the code in the controller files to get a feel for why each block exists.

Important! Notice that controllers are always plural. So be careful if you run ‘rails generate controller pirates’ instead of scaffold. Don’t mess this one up either unless you want your app to break.

Step 5 – Get in the sandbox and play with your localhost site:

> rake db:migrate 
  # this migrates your tables to the database

> rake server
  # this command will rackup a port for you to access your web app
  # "Starting Rack on port 4000" -> http://localhost:4000/

> rake routes 
  # this allows you to see what web app routes are available

The View files associated with your scaffold and routes are in the view folder. Check them out and add some HTML and some styling. There’s a lot more to do, but I found this to be a good start to wrap my head around the concept of MVC and Rails.

It Gets Better

We’re closing in on the 4th week of Flatiron School and so far it’s been great. I get up 10 minutes before my alarm clock every morning and I look forward to seeing my instructors and classmates. There are so many people in the class that I revel in learning something new about them every day. There are fun team-building exercises and plenty opportunities to get to know each other better – “lunch! oh yes, lunch!” But that’s not the whole story.

The 12-week immersive program is definitely intense. I have to be honest, it’s been a really trying few weeks for me. While there are 4-weeks of prework to complete, it hasn’t prepared me for what was to come. Bear in mind that I walked into this as a non-programmer with a geeky techie penchant.

What I’m learning, after interacting with other students, is that this type of course attracts many of a certain kind of person: the A-type. So let me digress for a moment. What’s an A-type person you ask? Well, in my interpretation we’re looking at a set of a highly competitive, high strung, multi-tasking, impatient and workaholic types. Now let me ask you this. You take a whole bunch of people like this, put them in classroom and tell them not to compete against each other… and what do you get? You get a bunch of people gauging the rate of their learning against everyone else’s, which translates to: [fingers spelling out “L” on my forehead].

We’re all strongly encouraged not to do this. But do we do that? Of course not. We go home, cry on our pillows and wonder why we’re such idiots (or maybe I’m just speaking for myself). The funny thing is that every person I’ve talked to claims to be the most behind in their learning. Seriously. We’ve come to the point that we’re even competing on who’s the most behind. I think I’ve made my point on personality type.

Anyway, what I’ve learned through this process is that learning how to program is challenging for many reasons, few of which are technical. Given the time and the inclination, I believe that anyone who puts their mind to learning any topic will eventually learn it. The challenge of this program is entirely affected by one factor: time. Can you learn it fast enough? This means battling your own ego on a daily basis, and learning how to deal with your frustrations.

I’m not going to pretend that I woke up one morning and everything magically became easy peasy lemon squeezy. It’s only week 4 and there’s a long way to go. Things are gradually getting better mostly through my own efforts. So here are some key take-aways: take ownership of your learning status (did I do all the homework? did I suffer the blank screen glare until I found a solution, or did I ride someone else’s coat tails?), stop comparing yourself against others (yeah, right), and chill the f*ck out (there are worse things that could be happening in your life). Savor those “yessss” moments when you figure out the most elementary things. And remember that at the end of the day, it gets better… albeit incrementally.

Learn Ruby Online


Source: Skillcrush

I’m the kind of person that likes books with pictures. I also tend to learn best by observing and grasping patterns. So lucky for me, there are a number of interactive Ruby learning tools available to suit different learning styles. I haven’t yet checked all of these out, so this post is part review and part reminder.

TryRuby
TryRuby is the most adorable browser-based learning tool ever. It’s hosted by CodeSchool. I love the super-cute storybook layout and characters. I first tried this out about 6 months ago and while it was very easy to follow, I didn’t really understand what I was doing or why. At the end of the module I didn’t get the point of what I had just done. That said, TryRuby is so irresistible that you will start typing Ruby.

RubyKoans
I love the concept of RubyKoans. It’s not browser-based. Instead you download a folder of ruby files and you go onto to follow a “path to enlightenment.” Having already learned the basics of Ruby, I’ve found this game to be very helpful in reinforcing what I’ve already learned to-date. It’s definitely helped me get a handle on some weaknesses. I wouldn’t recommend this to a complete programming newbie. This learning tool requires some familiarity with both a text editor and your terminal.

Rubeque
I just heard about this one, and I really think this is going to help me hone my skills. Last week I didn’t even know what an enumerable was, but this week I’m ready to throw on the punching gloves! This browser-based tool gets you to “hone your skills by solving small Ruby programs while competing against other Rubyists”. Challenges are listed in a table, which you can filter by level of difficulty. Awesome. Did someone just turn on the music? It’s the Eye of the Tiger, baby. Bring it on biznitch!

Ruby warrior While I fondly remember Adventure games of days gone by, I could never figure out what the heck word I was supposed to use to move forward. I sucked so bad at those games. This said I can’t wait to try this one. Go to this git repo and get instructions on installing the gem and then it’s off to the races. You’re a warrior climbing a tall tower in search of a precious Ruby at the very top. To get to the next floor, you need to write Ruby script for the warrior to battle enemies, rescue captives, and reach the stairs. Sweet.

Hackety Hack
All these interactive tools have me so spoiled. You watch video, a cute cartoon, compete against each other and role-play. As Tony the Tiger would say “It’s grrrrreat!” So honestly Hackety Hack, what are you thinking making me read words? Plus, I have to install an application that takes space on my hard drive? I don’t think so homey.

RailsforZombies
Classic learning tool by Codeschool to learn rails. Zombies and learning challenges: what more do you need? I’d write more but I haven’t finished it yet.

RubyMonk
I haven’t tried this one yet but if Ruby’s creator Yukihiro Matsumoto says he likes it, well then I’m just going to have to go ahead and try it.

Reference: https://speakerdeck.com/samnang/interactive-ruby-learning

Prelude to Coding

h—– layout: post title: “Prelude to Coding” author: Alisa Chang date: 2013-06-09 00:34 comments: true published: true

categories: [Adventure game, Musing]

$ emacs -batch -l dunnet
Dead end You are at a dead end of a dirt road. The road goes to the east. In the distance you can see that it will eventually fork off. The trees here are very tall royal palms, and they are spaced equidistant from each other. There is a shovel here.

Every once or twice in a lifetime, you’re given this incredible gift: The realization of a dead end, coupled with an opportunity to start over. You might choose to ignore the chance and unhappily continue along the same old but ‘safe’ path. But I won’t. Not me. Not anymore.
> Take shovel
Taken.
> Go East
E/W Dirt road
You are on the continuation of a dirt road. There are more trees on both sides of you. The road continues to the east and west. There is a large boulder here.

There’s something to be said about wanting to make a change but not knowing what to do about it. It’s called: Not enough data.

Here’s what my life’s looked like in recent years:

I used to want to become an animator. Maybe I should do that.
>dig
Digging here reveals nothing.

I love to cook. Maybe I should go to Culinary School.
>go west
Dead end

Hm. Maybe this job’s not so bad after all.
>go north
You can’t go that way.

Plus I’m good at it…
>climb
You manage to get about two feet up the tree and fall back down. You notice that the tree is very unsteady.
>damn it
I don’t understand that.
>screw you
I don’t understand that.

In the interim everyone around me keeps telling me to do what I love. Do what you love. What does that mean? I keep on my ‘safe’ path until…
You begin to shake a tree, and notice a coconut begin to fall from the air. As you try to get your hand up to block it, you feel the impact as it lands on your head. You are dead.
You have scored 0 out of a possible 90 points.
$

Some time after the coconut incident, it occurs to me that there’s always been one constant for happiness in my life: solving problems through applied technology. I dig it. I geek out on it. It’s my thing.

And this is sort of how I ended up at the Flatiron School.

I don’t think I’ll ever be done debugging my life. But what I do know is that it feels great being at Flatiron. I’m surrounded by awesome people that share an insatiable desire to learn. One week in, and it’s clear to us all that this is not your typical continuing-education course. The new order of the day is to let go of all pretenses and free your inner nerd. Like Avi said on Day 1: Be open to learn and don’t be an asshole.