Monthly Archives: January 2014

TIL: Make longer git commit messages…

and make longer git branch names.

Git is so ridiculously useful it virtually blows my mind. Or digitally, whatever.

I’ve got a project that is getting pretty deep in complexity and it’s now become apparent to me that there are branches that have long sections of completely un-referred to code.

I don’t know what’s in those branches. If I had named them more appropriately I might. Take a look at these branch names:

  active_merchant
  design
  event_edit
  google_maps
  location
* master
  prettier
  revoke_rsvp
  rsvp_button_context_dependent
  rsvp_goal_display
  stripe

^A really good example of bad branching practice. Bad bad bad. I mean this means at some point I named a branch the word ‘prettier’ and everybody knows. You know what my next branch name is going to be?

Yeah, I’m not sure either, but it’ll probably be as long as this sentence.

Refactoring a Pull Request for an open source project on GitHub

A couple of friends and I teamed up to build an admin interface for the BostonRB website. This is of course on top of our Breakable Toys and my side project. Launch Academy might be over, but the code is never finished.

Code is creation by sheer will.

We finished the interface and submitted a pull request but BostonRB’s organizers had a few tweaks they wanted made. I think this is a good experience that, as an open source developer, I expect to encounter often. I’ve decided to document the process for any engineers who may be early in their open source career.

Spec Inline Comments

This was the first of many helpful comments Dan left us to refactor before the pull request can be merged. FactoryGirl wasn’t working like we were used to on this project, so we hardcoded the specs in interest of time. The BostonRB site is actually written in Ruby 1.9.3 and runs on Rails 3, so I think it has something to do with that.

Firstly let’s put something in scenario string because a blank string definitely doesn’t feel right:

scenario 'admin views event' do
    location = Location.create!(:street => '33 harrison ave',
                                :city => 'Boston',
                                :state => 'MA',
                                :zipcode => '02135',
                                :name => 'Launch Academy')
    event_type = EventType.create!(:name => "Meeting")
    event = Event.create!(:location_id => location.id,
                          :event_type_id => event_type.id,
                          :date => '11/29/2014',
                          :start_at => '4:06am',
                          :end_at => 'midnight',
                          :rsvp_url => 'http://justusunlimited.com')
    visit admin_event_path(event)
    expect(page).to have_content(event.location.name)
    expect(page).to have_content(event.location.street)
    expect(page).to have_content(event.event_type.name)
    expect(page).to have_content(event.date)
    expect(page).to have_content(event.start_at)
  end

Then we’ll refactor object creation to use FactoryGirl:

scenario 'admin views event' do
    location = FactoryGirl.create(:location)
    event_type = FactoryGirl.create(:event_type, :name => "Meeting")
    event = FactoryGirl.create(:event, :location_id => location.id, :event_type_id => event_type.id)
    visit admin_event_path(event)
    expect(page).to have_content(event.location.name)
    expect(page).to have_content(event.location.street)
    expect(page).to have_content(event.event_type.name)
    expect(page).to have_content(event.date)
    expect(page).to have_content(event.start_at)
  end

Now we’ll run rspec in the shell and see what happens…

We get one failure:

view individual events for greater detail F
  1) view individual events for greater detail admin views event
     Failure/Error: event_type = FactoryGirl.create(:event_type, :name => "Meeting")
     ArgumentError:
       Factory not registered: event_type
     # ./spec/features/admin_views_event_spec.rb:11:in `block (2 levels) in '

Ok, so we don’t have an event_type factory. No big. Let’s look at the spec/factories.rb file and see what’s crackin:

FactoryGirl.define do
  factory :presentation do
    sequence(:title)         { |n| "Test Presentation #{n}" }
    presented_at   'May 10, 2011'
    sequence(:video_id) { |n| n }
    video_provider 'vimeo'
    sequence(:description)  { |n| "Test Description #{n}" }
    sequence(:slides_url) { |n| "http://slides.com/#{n}" }
    presenter       { create(:presenter) }
  end

  factory :upcoming_presentation, :class => 'Presentation' do
    title          "New Upcoming Presentation"
    presented_at   { Date.today + 20.days }
    presenter_name 'New Upcoming Person'
    description    'New Upcoming Description'
  end

  factory :presenter do
    sequence(:name) { |n| "Test Presenter #{n}" }
    url            'http://twitter.com/some_presenter'
  end

  factory :blog do
    author           'Brian Cardarella'
    twitter_username { |blog| "@#{blog.author.gsub(' ', '_')}" }
    feed_url         'http://a.blog.com/feed'
  end

  factory :user do
    sequence(:github_uid) { |n| "#{n}"}
    sequence(:name) { |n| "Ruby#{n}"}
    display_name "peeta"
  end

  factory :location do
    name "Mission Control"
    street "33 Harrison"
    city "Boston"
    state "Massachusetts"
    zipcode "02125"
    time_of_deletion nil
  end
end

So we’ll add the event_type factory:

  factory :event_type do
    name "Meeting"
  end

Cool. Let’s run the specs!

view individual events for greater detail F
  1) view individual events for greater detail admin views event
     Failure/Error: event = FactoryGirl.create(:event, :location_id => location.id, :event_type_id => event_type.id)
     ArgumentError:
       Factory not registered: event
     # ./spec/features/admin_views_event_spec.rb:12:in `block (2 levels) in '

Ah, no event factory either! But the test is passing the event_type creation without breaking so I am pleased.

Let’s add an event factory:

  factory :event do
    association :location
    association :event_type
    date "February 3rd"
    start_at "4:06"
    end_at "11:29"
    rsvp_url "http://justusunlimited.com"
  end

I wonder if associations will work like that in Rails 3. Let’s run the specs and find out.

Finished in 14.28 seconds
115 examples, 0 failures

Sweet success. Nothing is better than green from the test suite. One fix down, time to commit.

git commit -am"Added event and event_type factories. Refactored admin_views_event_spec with FactoryGirl"

Let’s see the next comment on the pull request:

Refactor method in sessions_controller

Here’s the sessions_controller in it’s entirety:

class SessionsController < ApplicationController

  def create
    client = GithubAuth.new(auth_hash, Octokit::Client)

    # Redirects the user to the home page if they're not a BostonRB member
    if client.is_member? == false
      redirect_to root_url, notice: 'Not a valid user. Must be a member of BostonRB github to sign in.'
      return nil
    end

    session.merge!(client.to_hash)

    redirect_to root_url, notice: 'Signed in!'
  end

  def failed
    redirect_to root_path, notice: "Authentication Failed"
  end

  def destroy
    session['project_night_coordinator'] = nil
    session['organizer'] = nil
    redirect_to root_url, notice: "Signed out!"
  end

  protected

  def auth_hash
    request.env['omniauth.auth']
  end

end

I pop dpickett’s conditional in place of mine and run the specs: ALL GREEN! Yay. I commit again and take a look at the next comment. It’s another spec that needs Factory Girl. Easy right? We just did it didn’t we? I replace the hardcoded values with Factory Girl calls and run the spec.

Forgot parentheses.

Had to change argument name.

I love how fast I recognize the errors and can fix them. It’s so fulfilling.

And the tests are green, or life is good. COMMITS.

The next comment is regarding a filename that changed. No  refactoring required here, just clarification.

Then we have another spec that needs Factory Girl. Piece of cake. So much less code, it brings tears to my eyes. Commit? Of course.

The next comment is interesting:

Duplicate behavior in similar admin controllers

So, the event_type admin controller and the location admin controller both check for organizer in a before filter. I wonder if this is more of a thought experiment than an actual fix request.

So, the actual fix for this is pretty silly. We forgot to change the controller inheritance to the AdminController so all we had to do was move the helper method and fix the inheritance and bang! We’re green once again.

The rest of the issues are Factory Girl implementations and the undeletion of a database.example.yml file, so I won’t go into detail about it. Hopefully this helps someone!

Keep calm, code on.

-Lorry

Launch Academy Wraps Up

I removed TurboLinks from my default rails template. Just to see what would happen. I call it launch_rails_new in homage to where I’ve developed my skills, Launch Academy, and the people there that have taught me.

I don’t just mean Experience Engineers, students too!

Everybody taught each other.The reversed classroom was the most productive learning environment I’ve ever seen.  It gives me faith in the technological community and it gives me hope for the future of education in America.

They thought MOOCS would be the most significant innovation in education that the internet has made possible. They were wrong.

Software bootcamps are an agile model of classroom instruction that is efficient. They are testament to immersive and concentrated learning. I’d be interested to hear from my classmates if they think it’s dollar-for-dollar the most valuable educational experience they’ve ever had.

The last five weeks have been the most intellectually stimulating period of my life. Programming really changes how you think about things: you realize less is more and that routines are key. Even my writing has become shorter (you may have seen my haikus).

Friday night and most of Saturday I spent as a teaching assistant at RailsBridge Boston. It was an amazing experience to see so many people install and learn a language in a day and a half. There must have been a couple dozen Launch Academy alumni volunteering at the event. Students teaching students: simply inspiring. Here’s a quick excerpt from the RailsBridge Boston about page:

Empowering Women with Ruby

Do you dream of someday writing software that helps people and improves the world?

Led by an all-volunteer team of seasoned, enthusiastic Ruby and Rails developers, the workshop introduces women of all backgrounds to the concepts, tools, and techniques of Ruby and Rails development. Our audience is those with no or little programming experience.

We welcome you to the Boston Ruby community. Whatever your goal is in learning to program, we hope to connect you with the tools to take the next step.

If you are at all considering learning Ruby and Rails, I highly suggest you consider getting your feet wet at this workshop. If you’re an established member in the Ruby community and you’d like to enjoy the honor of teaching others, they would appreciate your time as well. It was certainly an honor and pleasure for me, and I hope to volunteer there again in the future.

Speaking of the future, it’s about time I finish polishing this template so I can get started on my next project: a voting application. It’s gonna be pretty sweet,but I shouldn’t give away too much. For now enjoy this #launch_academy_selfie from the last day of class:

Last Day of Launch

Ping Pong Champion

Who will win? What will transpire?

Paul, No, Van succeeds!

We are in KrashPad.

Thanks for hosting this party,

Fly, watching good sports.

Van ping pongs like vim,

Foo Bar, and to be honest,

I might lose this bout,

Upcoming, Max and…

Nathan just walk’d out. They are

Paul’s courteous friends.

Now tis’ clear to me,

As I sit contemplating,

Kelly needs wifi,

Van is the victor,

What’s the wifi password? Uh…

I don’t remember.

Plenty to do now,

So it is true, I must go.

Peace to all my friends.

GitHub oAuth Part II: Using GitHub teams to authorize user permissions.

Last week, I posted an excellent guest post by the wonderful Lorry on how to integrate GitHub authentication into an existing Rails application. This week, we’re returning to that code to use GitHub team for authorization purposes.

Here’s the post, which was originally posted on Lorry’s blog, Cyber Sect:

We’re going to be using Octokit, GitHub’s API toolkit, so the first thing you want to do is add it to your gemfile.

gem "octokit", "~> 2.0"

Save and then bundle install.

Go back into the config/initializers/omniauth.rb because to use the functionality we want (the team authorization), we need to specify a code. So find the line that says to allow the app permission to access their teams


provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: "user"

The rest of our job is in the SessionsController. Add the following lines of code to the bottom of the file.


protected

def auth_hash
request.env[‘omniauth.auth’]
end

So, after a person is authenticated as having an existing account in GitHub using omniauth, GitHib returns you an authorization hash variable that you can access. This method is just a shorthand version of accessing that hash.

So, now, in your create method, you want to add the following code to the beginning of the method.


# sets the client for the Github API queries
client = Octokit::Client.new :access_token = auth_hash['credentials']['token']

What this is doing is taking the github users ‘access token’ (made available to you through auth_hash) and allowing you permission to access their GitHub account through the use of the octokit client. All your queries from here on out will be performed via your client.

You’re not going to hardcode any of the ID’s for the teams or organizations you are looking for. I suggest setting an environment variable in your .env file (untracked by github for maximum security). If you need a refresher as to how to set this, here is an example.


export ORG_NAME=name here
export ORG_ID=numbers here
export ADMIN_TEAMID=numbers here

With this set, we can now submit queries to check whether the authenticated person is a member of the team or not!

To query whether the user is a member of the organization, you do this

client.org_member?(ENV['ORG_NAME'], client.user.login)

The method .org_member? requires two argumentss. The first parameter is the name of the organization you’re testing. The second parameter is the name of the user you’re testing.

The response from GitHub will be a boolean, either ‘true’ if it’s true or ‘false’ if it’s not. This sets you up to be able to do a lot of cool things, like set session variables.

if client.org_member?(ENV['ORG_NAME'], client.user.login)
session[:member] = true
end

To check if the client is a team member or not, the process is similar with the exception that you’re testing the team ID and not the organization name.


client.team_member?(ENV['ADMIN_TEAMID'], client.user.login)

And there you have it! Now you know how to use octokit to access a GitHub user and check whether they’re a member of a specific team or organization. This is especially useful when working on collab projects with other folks and you want to limit their access (only admins can access certain actions or something). So, keep calm, and keep coding on!

Integrating Github OAuth into an existing Rails application

The students at Launch Academy love BostonRB. A couple of times a month, about half of my forty-person cohort floods into some local tech company’s office to take in some educational talks and low-pressure networking. It’s a really good time, and a few of us want to give back to the organization that’s welcomed us so warmly.

So we decided to overhaul the website. Together with a select few of my other cohort members, we tackled the administrative interface of the website and took it by storm. Confession: this isn’t actually me talking. This is my friend, Lorry, in a surprise blog invasion! Hi!

Show me your O-Face

If you want to follow along with this tutorial. Fork this branch and start from the same file that we did!

We’re going to be walking through the process of adding Omniauth Github authorization to the BostonRB site, but the series of events should apply to most Rails apps. So here we go!

First, go into your Github settings and create an application. This is where you get your Client ID and Client Secret token from Github, which you will need very soon. Fill in the new Application form, and you should be taken to a page that has your information.

IMPORTANT

Make sure your Authorization callback URL:
YOUR URL/auth/github/callback

For the purposes of development, do:
http://localhost:3000/auth/github/callback

If you don’t set it up in this manner, there is a strong possibility it wont work.

Next thing you do is add these gems to the Gemfile in the root directory:

gem 'omniauth-github'

group :test, :development do
gem 'dotenv-rails'
end

Bundle Install, and you’re ready to go!

You need to create a .env file in the root directory of your app. In that file,  set environment variables for your secret key like so:

export GITHUB_KEY= your github key here
export GITHUB-SECRET= your github secret token here

We don’t want people to know what your secret token is otherwise they can feign authorization. So add .env to your .gitignore file before you commit!

Next, you’ll want to perform a rails generate model user github_uid:string name:string display_name:string

^[Justus Note:] This generation will make your User model and migration, which you will edit a bit later.

Before you migrate, go into the migration file and set github_uid and name to null:false. Also, add the current index after you created the table.

class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :github_uid, null: false
t.string :name, null: false
t.string :display_name
t.timestamps
end
add_index "users", ["github_uid"], name: "index_users_on_github_uid", unique: true, using: :btree
end
end

After that, migrate. Look at you, you’re adding omniauth like a pro!

Create a new file in config/initializers called omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end

That’s calling upon the environment variables that you had just set in .env. We’ve come full circle.

Then, still in /config, enter the routes.rb file. There, add:

get '/auth/:provider/callback', to: 'sessions#create'

This URL needs to match the github callback url you had set when creating your Github client ID and token.

The configuration is done. Now to implement it.

Create a controller to handle your users when they have been signed in called ‘SessionsController’ It should be found in your app/controllers/ directory and called sessions_controller.rb

class SessionsController < ApplicationController
def create
redirect_to root_path, notice: 'You have successfully signed in!'
end
end

You’re just about done! Remember to validate the presence and uniqueness of github_uid, :name, and only the presence of github_token in your users model. An example of what your model should look like is

class User < ActiveRecord::Base
validates_presence_of :github_uid, :name, :github_token
validates_uniqueness_of :github_uid, :display_name
end

And, tada! You’re all set! Just remember to add the link to the your view, like so,

<%= link_to 'Sign In With GitHub', '/auth/github' %>

And you should be all set! Launch that server with Rails S and test that sucker out!

Test Driven Development: Bot-sauce.

Bot Sauce

My brain is working slower than usual this morning. I spent my Sunday writing code for an important Launch Academy project: the week eight check point.

This checkpoint is significant because it’s essentially a progress marker. The quality of my code will determine whether or not I get referred to employers on career day. The assignment involves a little bit of everything we’ve learned thus far in the program. It’s like a midterm if this were college, and college actually helped you find gainful employment.

The whole prospect is bit daunting.

I pride myself in my stoic resolve, so shortly after receiving the assignment, I ran…
rails new [app_name] -m https://raw.github.com/justuseapen/launch_rails_new/master/template.rb 
…which calls my pretty sweet Rails template from github and gets me off the ground with a Postgresql database and a test suite of excellent gems including rspec, factorygirl, capybara, and more.

Then I began writing acceptance tests.

I’ve been comfortable writing unit tests for a little while now. They come naturally to me and I enjoy using them to drive my workflow. Acceptance tests (integration tests) are a different story. I find myself fixing my tests more than fixing my code. At least I did.

This checkpoint was a turning point for me. Something about the TDD workflow ‘clicked’  and I was able to complete the project in one (stressful) day. I only had one major problem that held me up at the very end, and that’s because the strong params syntax is stupid.

That was an interesting moment: all my tests were green, but the browser interface wouldn’t save associations. Talk about frustration.

This excites me. TDD excites me. I am passionate about this stuff and I am pumped to know I can build useful tools quickly, and efficiently.

I’m going to apply my newfound passion to Distracker. She needs some good acceptance tests, and some good ajaxy magic.

Wish me luck.

 

tdd workflow

Distracker is Live

“SQUIRREL!”

If you’re anything like me, the internet has destroyed your focus.

BRB, need to make eggs in a basket smothered in cheese and mirepoix.

What was I saying?

Oh yes, distractions.

So as readers of this blog might know (all three of you), Launch Academy curriculum mandates the design and execution of a web app known to Launchers as a “breakable toy”. The idea is to teach students the Ruby on Rails framework through doing. Personally doing is my preferred mode of skill acquisition, thus, my favorite part of the program.

I decided early on that Distracker would be my breakable toy (though it’s gone through many names over the last few months).

It began as a terminal program (ask me if you want it) and then, to qualify as a breakable toy, I expanded the concept into an (almost)full-fledged web application. I’m still considering releasing the terminal program as a gem for developers.

In all, I restarted development on Distracker at least half a dozen times. It’s been a great learning experience and I intend to continue building it and adding features.

If you’re a developer, please fork the github repo and submit a pull request. I’m still a new developer and there is only so much I know how to do.

I welcome comments, suggestions and critique. Either here in the comments or through Github as an issue.

Your help would be greatly appreciated in my effort to track and eliminate this:
Image