Category Archives: Rails

Season of Ruby – Things Are Starting To Click

The danger with doing any online tutorial, even one as good as the Michael Hartl Rails Tutorial, is that if you aren’t careful the only benefits you will have at the end is that your typing skills have improved and you have the marketable ability to cut-and-paste large snippets of code.  At some point you need to start driving the bus.  Today I felt like the Ralph Kramden of Rails.

Editor’s Note: I am not actually old enough to have seen the Honeymooner’s, I just remember in my college days the reruns were on at 11PM, just before Star Trek at midnight (also in reruns).

The last few chapters I have been making an effort to implement the code without looking at the solution from the tutorial.  Today I stepped it up a little further by taking more control of writing and defining the tests too.  It really paid off today as I felt like I took ownership of the app and the technical choices.

Chapter 10 starts out by defining the functionality needed for editing a user.  I looked over the wireframes and had a good idea about the functionality I wanted.  I glanced at the titles of the 1st three tests: get page successfully, has correct title, and includes link to change gravatar.

From a pure TDD approach, doing the simplest thing that works, I was able to get these tests to pass with the following code.

app/views/users/edit.html.erb

<h1>Edit User</h1>
<a href="http://gravatar.com/emails">change</a>
app/controllers/user_controllers.rb
 class UsersController < ApplicationController
    ...
    def edit
      @title = "Edit user"
    end
    ...

Obviously this is not enough to implement the final solution, but it is enough to get the tests to pass, and in my experience additional functionality should be driven by the tests.  From the perspective of a Rails noob I felt that these were valuable tests because they proved out the plumbing and set the table for more complex tests/functionality.  Now it was time to look at the tutorial’s solution.

I was surprised to see that the tutorial solution included the form and all its associated fields.  Now this is not a knock on the tutorial, it is a very good tutorial.  I love this tutorial, but while it introduces some concepts of TDD and its primary goal is not to teach TDD.  But clearly there was a disconnect between the solution and the tests.

So I added the tests for the fields, and now was happily back to red.  Yes Virginia, real developer’s love failing tests, they are a sign of progress.

spec/controllers/user_controllers_spec.rb

   it "should have a name field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[name]'][type='text']")
    end

    it "should have an email field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[email]'][type='text']")
    end

    it "should have an password field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[password]'][type='password']")
    end

    it "should have an confirmation field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[password_confirmation]'][type='password']")
    end

Getting to green was fairly trivial, and I was able to cut-and-paste a lot of the code from “new” and make a few minor mods.

app/views/users/edit.html.erb

<h1>Edit User</h1>
<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages', :object => f.object %>
  <div>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div>
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </div>
  <div>
    <%= f.label :password_confirmation, "Confirmation" %><br />
    <%= f.password_field :password_confirmation %>
  </div>
<div>
  <%= f.submit "Update" %>
</div>
<% end %>
<div>
  <a href="http://gravatar.com/emails">change</a>
</div>

My tests were passing but now I had quite a bit of duplicated code in my app/views/users/new.html.erb and app/views/users/edit.html.erb files.  It was time for the 3rd piece of the red-green-refactor cycle.

Thinking back to earlier chapters, I thought what I would like to do is to implement a partial view that encapsulated the user forms.  After some googling about how to pass parameters into a partial view I ended up with the following partial view

app/views/shared/_user_fields.html.erb

<div class="field">
  <%= f.label :name %><br />
  <%= f.text_field :name %>
</div>
<div class="field">
 <%= f.label :email %><br />
 <%= f.text_field :email %>
</div>
<div class="field">
 <%= f.label :password %><br />
 <%= f.password_field :password %>
</div>
<div class="field">
 <%= f.label :password_confirmation, "Confirmation" %><br />
 <%= f.password_field :password_confirmation %>
</div>

And the edit.html.erb was a lot cleaner now and my tests were still passing.
app/views/user/edit.html.erb

<h1>Edit User</h1>

<%= form_for(@user) do |f| %>
 <%= render 'shared/error_messages', :object => f.object %>
 <%= render 'shared/user_fields', :f => f %>
 <div class="actions">
 <%= f.submit "Update" %>
 </div>
<% end %>

<div>
 <a href="http://gravatar.com/emails">change</a>
</div>
<pre>

Making the necessary changes to new.html.erb completed the process.
app/views/user/new.html.erb

<h1>Sign up</h1>
<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages' %>
  <%= render 'shared/user_fields', :f => f %>
  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

Run the tests one more time…and still green.

It was a really good day in Rails land.  None of this was rocket-science, but I felt like I knew what I wanted to do and how to do it (with just a few minor hiccups related to syntax and mechanics).

Advertisements

Season of Ruby – Iteration 4 Retrospective

Iteration 4? Wait, shouldn’t I be on Iteration 5?  Yes, but as expected work reared its ugly head and the Season of Ruby got pushed to the back of the line.

I am now through Chapter 8 of the Ruby on Rails Tutorial.  I wish I had tracked the actual time spent on the tutorial, that would have been useful information for anyone wishing to follow the same roadmap.  I would estimate I have spent around 14-16 hours through the first 8 chapters.

What Went Well

  • In the interest of trying to get as much as possible, I am resisting the urge to cut-and-paste from the tutorial.  You learn a lot from mistakes, big and small, so there is a lesson to be learned when you type “name” or “@name” when what you really needed to type “:name”.
  • I still think one of the strengths of this tutorial is the focus on TDD.  As I have started to get more comfortable with the environment, I have also been trying to implement solutions on my own after writing the tests from the tutorial.  That makes me feel like I am starting to get more of a lay of the land.
  • Used the FactoryGirl gem to simulate model objects for testing.
  • Got my shiny new MacBook Pro and have switched all my Ruby and Rails development from Windows.  It was really cool once the environment was set up to grab the repo of github and pick up right where I left off.  BTW, I used the thoughtbot laptop project to get my system all set up for Rails development.  Went pretty smoothly.

What Can Be Improved On

  • I feel a little like how I felt during the Ruby Koans, that I am gaining a false sense of knowledge by following the tutorial.  It has been really helpful to get me moving forward with Rails, but you are still following a well-defined roadmap.
  • I want to finish the tutorial because I think there are several more lessons to learn and it will be a great reference to look back on, but I am anxious to start from a clean sheet of paper and make a ton of mistakes.  That is when the real learning will happen.
  • I have been pretty good about not doing a lot of cut-and-paste from the tutorial, but at times it is hard.  Just need to keep forcing myself to resist doing that.
What Am I Going To Do To Improve
The most learning has come in cases where I have tried to implement my own solutions after using the tests as provided from the tutorial.  From this point on, that will be the approach I will use.  Then when I have a passing test I can look at the tutorial and compare my solution against the tutorial solution and take that as a refactoring exercise.  It may take longer, but it will pay dividends down the line.

Iteration 5 Stories/Tasks

Chapters 9 and 10 of the Ruby on Rails Tutorial, implementing my own solutions first after using the tutorial tests to get to “red”.

Halftime Review of Michael Hartl’s Ruby on Rails Tutorial

I am a newcomer to Ruby and Ruby on Rails, so when I wanted to get started with Rails I looked around quite a bit for a good starting point.  I finally settled on Michael Hartl’s Ruby on Rails Tutorial.  I am about halfway through with the tutorial, and I am really pleased so far.  This is a great tutorial for a lot of reasons, but the aside from just teaching Rails, he is also teaching good development practices such as:

  • How to use git effectively.  The tutorial starts out with git basics and then quickly moves on to integration with github, working on branches when adding new features, and merging changes back into the master.
  • Focus on testing.  We start out with RSpec writing unit tests, but then also add in integration tests.  He also follows a TDD approach for a lot of the tutorial where the tests come before the code, a practice that I believe strongly in.
  • Stresses good developer practices like running your tests before and after merging a branch.  Sure the merge probably went fine, but be a good citizen and test it before you push it up to github.
  • Refactoring your code to reduce duplication and make it more readable and maintainable.
  • Shows how to deploy your code up to heroku
  • Introduces real world work practices like sketches and wireframes.
The focus on testing, refactoring, and general good developer practices is important to me.  These are practices that I have been using for a long time, but it is great to see them so much a part of Ruby on Rails.  Just seeing that standard project hierarchy includes a place for tests tells you it is ingrained in Rails.  I really loved this quote from the tutorial

If you ask five Rails developers how to test any given piece of code, you’ll get about fifteen different answers—but they’ll all agree that you should definitely be writing tests

As far as the Rails side of the tutorial goes, I think after my initial environment snafu (that’s all on me), things have been going great.  I am starting to see more of how Rails implements MVC.  MVC is obviously not a new concept, it’s been around for a while, but each framework and environment uses it differently.  I also really enjoy the ordered structure of a rails project and can see what an advantage it is to have this kind of common project structure.  I know ASP.NET MVC also tries to use a standard project hierarchy, but rails felt a little cleaner and more intuitive.

After some simple applications to get your feet wet and make sure your environment is good to go, the tutorial uses a micro-blogging application to slowly walk through the different capabilities in rails.  The tutorial also explains some of the “magic” that goes on under the covers that Rails provides for you.  This has encouraged me to route around (pun intended, thanks) to understand more of the magic.  Aside from routing, we have also hit a bit on database integration and migrations, some CSS, and partials.

One thing this tutorial will not teach you is a lot of Ruby, and the author is quite clear about that.  He provides some good references for learning more Ruby, but the focus here is on Rails, and he keeps the amount of Ruby necessary to a minimum.

I am about halfway through and am hoping to finish up in the next 2 weeks.  It is a little slow going because as I learn I often go off to investigate different aspects of what I am learning.  Finishing the tutorial will not be the end of the journey, but it certainly has helped get it going in a good direction.  I recommend it highly to anyone interested in getting started with Ruby on Rails.

Season of Ruby – A Bad Day Of Fishing

I have been really excited to get going with Michael Hartl’s Ruby on Rails Tutorial.  Skimming through the table of contents and the introduction, I liked that he makes testing such a focal point of the tutorial.  I also liked the Comments for Various Readers section.  I fit into the “Experienced programmers new to web development” camp, and after reading the introduction I knew  that this would be a great tutorial for me.

The first section was well laid out, and focused on getting your environment set up.  It also touched on using git and github which is starting to feel like old hat for me, but then it ended with deploying the sample app to heroku which was a new thing for me.  As someone experienced in software development, but new to web development, it was great to have the heroku deployment so well explained and easy to do.  I was feeling quite full of myself.

Then came the 2nd chapter…

Someone once said “A bad day fishing is better than a good day at work”.  Oh yeah, tell that to Captain Quint, he looks like he is having a pretty bad day fishing.

A Bad Day Of Fishing

Now you could argue that he’s actually just having a good day at work, since technically, as a fisherman, he is at work.  But I digress. Up to this point my Ruby experience has been all pie and ice cream, but today was a bad day of fishing with Ruby.

The author goes to great length to explain that the tutorial uses an older more stable combination of Rails/Ruby versions and that is what you should install.  But I am sooooooo much smarter than that and besides, I want to use the newest stuff.  To say the least, I ran into a lot of problems with getting the right combinations of Ruby, Rails, sqlite, etc, etc working.  I learned a lot about gems and bundler along the way.  I think things were further complicated by running on a Windows box as well.

After a lot of time fighting my environment, I realized I was fighting the wrong battle and the smart thing to do was to get the environment set up as the author intended to be able to get the most out of the tutorial.  Once I made that decision I was back on the happy path and am looking forward to moving on to more in-depth parts of the tutorial.  I don’t feel like it was a wasted experience, because I did learn quite a bit digging around.  I imagine this can be a significant issue for Rails projects, especially as new versions of Rails, Ruby, or different gems roll out and that the correct dependencies need to be addressed.  It reminded me a lot about the “DLL Hell” days of Windows before .NET.

The take-away is if you decide to do this tutorial follow the author’s advice and set up the environment as specified.  The lessons to be learned are more to the core of Rails and running the latest version of Rails or the application’s dependencies is not important.  And now that I am on the right track I am looking forward to moving on to more advanced sections of the tutorial.