Review: Agile Web Development With Rails, Fourth Edition (Part I)


    With a full house of kids, I don’t get as much of a chance to dabble in technologies that I’m not using at work.  So, I am much more selective in what I choose to learn.  I also seemed to be moving jobs enough and bouncing back and forth between the JVM (Java, Groovy) and the CLR (VB.Net, C#) that I was already expanding my language horizon on an annual basis.  While, I’ve been watching Rails from a distance for quite some time, I never seemed to have the bandwidth to take the jump and force myself to sit down and learn it.  For whatever reason, I’ve decided that now is the time.  After asking several friends which book to start with, I settled on Agile Web Development with Rails [PragPress].

    Disclaimer:  As of this writing, the fourth edition is still in beta as is Rails 3.  I know the book is a work in progress, but I am reviewing it as-is.

    Summary

    The purpose of this blog post is to review Part I: Getting Started.  Part I is divided into four chapters: “Installing Rails,” “Instant Gratification,” “The Architecture of Rails Applications,” and “Introduction to Ruby.”  These first four chapters are intended to lay the foundation needed to understand the deeper material covered in the rest of the book.  Additionally, they serve to whet the appetite of the reader by walking him through some very basic examples.

    Chapter 1: Installing Rails

    When I first started looking at Rails, I was using the third edition of this book and installing Rails 2.  At the time, I was using my Windows 7 box.  I found the walk through for installation to be helpful and complete for getting Rails up and running on Windows.  This time around, I decided to go with my Ubuntu linux environment.  I still needed to install both Ruby and Rails.  And again, I found the guides to be very helpful to get things running.  One section that I found a bit jarring was the sidebar entitled, “Upgrading RubyGems on Linux.”  This sidebar lists several methods for upgrading RubyGems for different versions of RubyGems and different linux distributions.  The slightly odd part is that there is no explanation for which method is needed for which setup.  Perhaps this is because there are so many linux distributions out there that listing them all would take another page (or more).  Regardless, I found it odd that I was encouraged to keep trying the different methods until I found “the one that works for [me].” 

    The authors have also thoughtfully included a section discussing different editors and integrated development environments (IDE’s) that are available.  When I first read this section in the third edition, I learned about a nice text editor for Windows that I didn’t know existed (E-TextEditor).  This time around, I decided to stick with my linux text editor of choice.  I briefly looked at using an IDE like RubyMine, but the Rails 3 version is still in beta (since Rails 3 is as well).  I decided that sticking with a bare editor was fine for learning.  I’m a command-line junkie anyway.

    Overall, I found the installation guide to be plenty thorough.  Perhaps that’s because I intended to work with all of the defaults (including sqlite for a database).  Perhaps if I would have deviated more from the happy path, I would have had more of a problem.  Then again, the authors have done a good job at pointing the reader to the necessary, external resources when they choose to step away from the default installation.

    Chapter 2: Instant Gratification

    In 13 pages, the reader is walked through creating a Hello, Rails application.  This allows the reader to quickly experience the power and simplicity of Rails.  Because the chapter accomplishes its goal very well, I don’t have much to mention.  By the end of the chapter, the reader can have a very simple Rails application running in their development environment and handling requests.  There are plenty of screen shots in just the right places, and I was never left with a question as to how to do something.

    Chapter 3: The Architecture of Rails Applications

    This chapter covers the basics of the Rails architecture.  Models, Views, and Controllers are each discussed in turn.  The basic request pipeline is described and illustrated. Additionally, there is a brief explanation of ActiveRecord.  The chapter does a good job of teaching where different code concerns go within the architecture.  The responsibilities of the Model, View, and Controller are covered well.  Perhaps my reading of this chapter is skewed because I’ve worked with multiple MVC platforms already.  However, I found that the topics were covered in sufficient (brief) detail.  By the end of the chapter, the reader has a good idea of how the various files are laid out within a Rails application and what responsibilities are addressed by each of the major components of the system.

    Chapter 4: Introduction to Ruby

    This chapter is new for the fourth edition, and I found it to be a very welcome addition.  Having never coded in Ruby before, I found this chapter to be quite informative.  The authors assume that the reader knows nothing about Ruby.  Since I am squarely in the target audience for this chapter, I can honestly say that I learned a great deal here.  The authors have covered object-orientation, data types, logic, and structures. 

    The authors also cover a small set of Ruby idioms.  I found this to be very helpful since the bulk of my programming experience is in static languages.  The coverage of Ruby idioms is only slightly longer than a single page, but I’ve already found it useful.

    Conclusion

    So far, I’ve found this book to be a very enjoyable, informative read.  I look forward to continuing on (and to posting some reviews).

    Your Best Foot Forward: Writing An Effective Technical Cover Letter


    Are you sure that your cover letter is doing its job?  How do you know if you’ve written an effective cover letter?  If you aren’t getting a call back on your application, your cover letter may be the problem.

    How Cover Letters are Read

    When I worked for my former employer, I had the opportunity to review and screen many applications.  Most of those applications were limited to simply a resume.  And, to be honest, most of those applications were garbage.  The resumes were poorly written for a variety of reasons, and most came without a cover letter.

    To understand how to write an effective cover letter, you must first understand how your job application is going to be read.  In truth, job applications are rarely if ever read in their entirety.  Job applications, including resumes and cover letters, are scanned.  In large companies, the applications are digitized with text-recognition software and searched for keywords.  Without the right keywords, your name may never make it past the first line of computers to a human’s eyes.  Once in front of a real person, your information will be scanned again, and an opinion will be formed very quickly as to whether or not you may be qualified.  In some cases, I would decide that a person was no longer worth my time within 15 seconds. 

    Getting Past the Initial Scan

    So, how does someone get past the initial scanning?  Whether your application is scanned by a computer or a human, keywords are critical.  Be sure to include a section for keywords in the experience section of your resume.  Also, be sure to include the most important keywords in your cover letter itself.

    The most important question to ask yourself when writing your cover letter is, “why would my intended audience read this longer than five or ten seconds?”  If you can’t answer that question clearly, then your cover letter stinks.

    Remember that the first person to read your application may have zero experience in your field.  This could easily be a human resources worker or a recruiter that has little knowledge of the actual meaning behind the content of the job description.

    Have a Purpose

    Usually, a cover letter is placed with an application for a job with a published job description.  This is known as an application letter.  Other types of cover letters include the prospecting letter to inquire about possible positions and the networking letter to garner assistance in a job search.  Regardless of which type of cover letter you are writing, you must know the exact purpose for writing and focus all of your writing toward that purpose.  In this post, I am referring to the application letter specifically.  For more information about other cover letters, see the links section below.

    Start With a Brief Summary

    If you are experienced and the job description is specifically looking for experience, be sure that the first sentence includes the word “experienced.”  Use your most important keywords in the first few sentences.  Be sure that the very first sentence gives the reader good reason to continue reading.

    Connect the Dots

    In the body of the letter, connect the dots between the job description and your resume.  You have already modified your resume to fit the job description, right?  If not, do so.  Immediately.

    If you set down a copy of the job description next to a copy of your resume, you should be able to draw lines from the requirements and desires in the job description to the experience, skills, and education in your resume.  First, make those connections as obvious and easy as possible directly in your resume.

    However, remember that your application will be getting scanned rather than read in depth.  This is where your cover letter can shine.  The application cover letter should clearly and concisely draw the connection between the job description and your qualifications listed in your resume.  Call out specific points in the job description and then explain how you meet those qualifications. 

    Do not leave anything for the reader to deduce, figure out, or otherwise determine for himself.  Assume the read has no idea who you are and that you have fifteen seconds at most to get them to listen to you.  Someone from outside your industry should be able to set your cover letter down next to the job description and determine that you have enough qualifications to make it to an interview.  If the job description requires, “experience with Java web frameworks,” then your cover letter should include those exact words.  Here’s an example:

    I have experience with Java web frameworks including Struts, Tapestry and Wicket.

    Leave nothing to chance here.

    Follow Up

    Be sure to let your audience know how they can contact you.  Request a next step.  Usually, this is a request for an interview to discuss how your qualifications fit with the position you are applying for.

    Finish your cover letter indicating how and when you will follow up with your application.  This could be a call or some other form of subsequent contact.  At a minimum, be sure to make the follow up contact within the time frame you’ve listed and be certain that they have received your application.

    Be sure to indicate other attachments including your resume and any references that you have provided.  The standard, “references are available upon request.” is usually adequate unless the job application specifically requires that references be submitted.

    More Reading

    About.com has a decent guide including sample cover letters.

    Virginia Tech Career Services also seems to have a nice guide.

    Organizational Knowledge Sharing


    Recently, I have been reading Chasing The Rabbit by Steven Spear.  This is a methodical dissection of market leading organizations and what they do to gain and maintain the lead in their respective markets.  Spear looks at a wide variety of companies in various sectors including defense, health care, and automotive.  Soon, I will be writing a blog series to look at the main concepts covered by Spear and how those concepts apply to software companies specifically.

    In the interim, I would like to gather a bit of data from you, dear reader.  One of the key capabilities identified by Spear is the ability of an organization to rapidly share knowledge within its structure.  So, any given problem gets solved exactly once.  That solution gets

    Why Chrome OS Will Succeed (in a limited market)


    Randall Kennedy released an excellent analysis of the Chrome OS that I invite you to read.  In that analysis, Mr. Kennedy outlines why he believes that the Chome OS is doomed to fail miserably.  Though I haven’t seen Chrome OS myself, I believe his read on the operating system is solid.  This is a stripped down operating system that basically locks the user into web applications with the Chrome browser as the interface.  The operating system is at its core a paired down version of linux and does not seem to support running desktop applications.  Because this is a this OS that only supports the web browser, Mr. Kennedy’s analysis is that no user will want this running on their computer.  This is where Kennedy misses the point.

    From reports including Mr. Kennedy’s article, Google will be releasing Chrome OS on a limited set of hardware.  Instead of having to deal with device drivers for a wide array of display adapters and whatnot, it appears that Google will be shipping Chrome OS on a constrained set of netbooks.  Kennedy looks at this limited set of hardware combined with the limited features of Chrome OS and determines that with all these restrictions, nobody will use the operating system.  This is where Kennedy has missed the point.

    Personally, I would be happy to have a netbook running Chrome OS on it.  With access to Google apps, I will still have simple spreadsheets and word processing inside of the full functional web browser.  I would use a Chrome OS netbook like, well, a netbook.  I would surf the web and check email.  My wife and I would keep it in the kitchen for looking up recipes on our favorite recipe sites.  My wife would use it to waste time on Facebook, er… “see what her friends are up to.”  I would have to find a web Twitter client that I like since I’m guessing I wouldn’t be able to run TweetDeck.  But, that’s not a major loss.

    I don’t want to run VisualStudio on my netbook.  I probably wouldn’t care if I couldn’t run Word.  As long as the user is looking for a simple web appliance that is better than a mobile phone while being lighter and less expensive than an entry laptop, then I think a Chrome OS netbook could be a suitable device.   Yes, this is a narrow market.  No, Google won’t be making a big dent in Windows (or Mac for that matter) with this device.  However, this could get them a decent footing in a tough market to make headway into.

    I, for one, welcome our new robot overlords

    Up and Running With SQuirrel SQL and SQL Server Express 2005


    Squirrel SQL provides some nice features that SQL Management Studio does not have out-of-the-box including auto-completion of table and column names.  Granted, Red Gate makes tools for Management Studio to get the same functionality, but SQuirrel SQL is open source and free.

    There are plenty of articles and blog posts around that cover installing SQuirrel, using JDBC with SQL Server, and connecting to SQL Server Express.  However, I ran into enough snags getting SQuirrel to connect to my installation of SQL Server Express that I thought a brief how-to was in order.  I will show the basic steps that I used to get SQuirrel talking with the database using integrated Windows security.  I will also provide some links to useful articles for further reading.

    I assume that the machine is starting with a current installation of SQL Server Express.  I have tested the information here against the 2005 version.  Some settings may be different for 2008.

    Initial Installs

    Download and install the following requirements:

    1. The Java Runtime
    2. SQuirrel SQL
    3. The Microsoft SQL Server JDBC Driver

    Follow the installation instructions for each of the above as detailed on the provided web sites.  This was all pretty straightforward in my experience.  The tricky part was setting up the JDBC URL correctly and getting the right driver .dll files copied around so that the JDBC driver can use integrated security.

     

    EDIT:  Determining the Port Number For Your SQLEXPRESS Instance

    For the MS JDBC driver to connect through TCP/IP, this protocol must be enabled for the database instance that you wish to connect to.  SQL Server Configuration Manager is your friend for this.

    1. Launch SQL Server Configuration Manager
    2. In the left pane, navigate to SQL Server Configuration Manager (Local) -> SQL Server 2005 Network Configuration -> Protocols for
    3. In the right pane, right-click “TCP/IP” and enable this protocol if it is not already enabled.
    4. Double-click “TCP/IP”
    5. Click the “IP Addresses” tab
    6. Scroll to the bottom
    7. Set a port value in IPAll -> TCP Dynamic Ports

    Setting the TCP/IP port forces the instance to use a constant port rather than relying on the SQL Server Browser service for forwarding connections.  You’ll need to know the port number of the instance to connect through TCP/IP

    Configuring the JDBC Driver in SQuirrel

    SQuirrel supports connections to any database that has a corresponding JDBC driver.  And, there are JDBC drivers available practically every major database as well as plenty of flat file formats.  For connecting to SQL Server, SQuirrel must be told where to find the Microsoft driver that was installed above.

    • Start SQuirrel SQL
    • Click on the “Drivers” tab on the left side
    • Either find the existing entry for the Microsoft JDBC driver or add a new one
    • Setup the example URL.  Since I am using Windows security, my example URL looks like this:
      • jdbc:sqlserver://localhost:8433;instanceName=SQLEXPRESS;integratedSecurity=true;databaseName=[catalog];
    • Click the “Extra Class Path” tab
    • Click the “Add” button
    • Navigate to and select the sqljdbc4.jar file in the installation directory of the Microsoft SQL Server JDBC Driver
    • Set the class name to com.microsoft.sqlserver.jdbc.SQLServerDriver
    • Click OK

    If you are using SQL Server Authentication or need other options, more detailed information can be found on the Microsoft web site for this driver.

    Setting Up for Integrated Security

    In order for the JDBC driver to use integrated security, it needs access to a particular .dll file named “sqljdbc_auth.dll.”  The JDBC driver ships with three different versions, and the required version varies depending on whether the 32-bit or 64-bit version of Java has been installed.  The right .dll can be found under the JDBC driver installation directory at:

    <_installation directory_="">auth

    EDIT: It appears that the required version depends on the architecture of SQLEXPRESS that is installed.  So, with a 64-bit JVM and 32-bit SQLEXPRESS, I required the 32-bit auth dll.  When I switched to SQLEXPRESS 2008×64, I had to switch to the 64-bit auth dll.

    In order for the driver to find the .dll at runtime, copy the appropriate “sqljdbc_auth.dll” into a folder that is already on the system path or add an entry to the PATH environment variable for the directory that contains the .dll file.  Do not put the auth .dll under a path that contains spaces.  This will NOT work.

    If you get the wrong version of the .dll, or if Squirrel cannot find the .dll, you will see a message like

    JcmsImport: This driver is not configured for integrated authentication.

    Correct the problem by shutting down SQuirrel, setting up a different auth .dll on the system path, then relaunching SQuirrel and trying again.

    More detailed information about using this driver with integrated security is available from Microsoft.

    Configuring The First Alias

    In order for the JDBC driver to connect to the correct instance, it needs to know the port for that instance.  This was one of the details that I initially overlooked.  My SQLEXPRESS instance is NOT at the default port.  Rather, I had to look in SQL Server Configuration Manager to find the port number.  To determine the port for a particular instance, launch Configuration Manager and click “Protocols for –> TCP/IP (double click) –> IP Addresses” Scroll to the bottom to see “IPAll” and note the TCP Port setting.  This is the port number that needs to be in the JDBC url.  For my installation, I used 8433.

    To add a new alias follow these steps:

    1. Click on the “Alias” tab on the left side of SQuirrel.
    2. Click the “+” symbol to add an alias.
    3. Set the name
    4. Select the Microsoft JDBC Driver that was configured earlier
    5. Edit the URL to set the initial database catalog
    6. Use the “Test” button to test the connection to the database.

    Further Reading

    Unused Constructor Dependencies


    Some classes simply require multiple dependencies that don’t always get used.  When testing such a class, there are several options for supplying the constructor parameters that will not be used.  I prefer to write tests that are as intention-revealing as possible. 

    To demonstrate, here is a simple example of a payment processing class.  Think of the credit card machines that are found at the local grocery store.  The basic flow is for the customer to approve the charge amount, then swipe their credit card or debit card and complete the transaction.  Below, the PaymentProcessor is responsible for displaying the current charge amount to a user, verifying that they accept the amount, and then sending transaction information to the bank to request funds.  Here is an example implementation:

     

       1: public class PaymentProcessor

       2: {

       3:   private readonly IBankInformationReader _bankInformationReader;

       4:   private readonly IBankService _bankService;

       5:   private readonly IUserVerification _ui;

       6:  

       7:   public PaymentProcessor(

       8:     IBankInformationReader bankInformationReader, 

       9:     IBankService bankService, 

      10:     IUserVerification ui)

      11:   {

      12:     _bankInformationReader = bankInformationReader;

      13:     _bankService = bankService;

      14:     _ui = ui;

      15:   }

      16:  

      17:   public bool ProcessPayment(double amount)

      18:   {

      19:     if (!_ui.VerifyAmount(amount))

      20:       return false;

      21:  

      22:     var bankInfo = _bankInformationReader.GetBankInformation();

      23:  

      24:     return _bankService.RequestFunds(amount, bankInfo);

      25:   }

      26: }

    </div> </div>

     

    The PaymentProcessor depends on IBankInformationReader, IBankService, and IUserVerification.  If the user declines the payment amount, then processing should stop immediately.  You can see this behavior above in lines 19-20.

    Under this scenario, then PaymentProcessor should never interact with either the IBankInformationReader (used for reading the credit card swipe) or the IBankService (used for submitting the transaction).  My preference is to pass null for the dependencies that shouldn’t be used, but to do so in an intention-revealing way.  Here is an example:

     

       1: [Test]

       2: public void should_not_charge_if_the_user_declines_the_amount()

       3: {

       4:   double amount = 4.50;

       5:  

       6:   IBankInformationReader cardReaderShouldNotBeUsed = null;

       7:   IBankService bankServiceShouldNotBeUsed = null;

       8:   

       9:   var ui = Stub<IUserVerification>();

      10:   ui.Stub(x => x.VerifyAmount(amount)).Return(false);

      11:  

      12:   var processor = new PaymentProcessor(

      13:     cardReaderShouldNotBeUsed, bankServiceShouldNotBeUsed, ui);

      14:  

      15:   processor.ProcessPayment(amount).ShouldBeFalse();

      16: }

    </div> </div>

     

    Rather than simply passing the value null to the constructor in lines 12-13, I’ve used some local variables.  This allows the test to clearly show intent.  In this case, the test states that PaymentProcessor should never use the bank service or the card reader when the user declines the transaction.  And, by using a null, we know that the test will fail if the PaymentProcessor tries to use those dependencies. 

    There is another option which is equally intention revealing but somewhat more noisy.  We could use a mocking framework to generate the dependencies and then verify at the end of the test that they have never been used:

     

       1: [Test]

       2: public void should_not_charge_if_the_user_declines_the_amount()

       3: {

       4:   double amount = 4.50;

       5:  

       6:   var cardReader = Stub<IBankInformationReader>();

       7:   var bankService = Stub<IBankService>();

       8:   

       9:   var ui = Stub<IUserVerification>();

      10:   ui.Stub(x => x.VerifyAmount(amount)).Return(false);

      11:  

      12:   var processor = new PaymentProcessor(

      13:     cardReader, bankService, ui);

      14:  

      15:   processor.ProcessPayment(amount).ShouldBeFalse();

      16:   cardReader.AssertWasNotCalled(x => x.GetBankInformation());

      17:   bankService.AssertWasNotCalled(x => x.RequestFunds(0, null), 

      18:     o => o.IgnoreArguments());

      19: }

    </div> </div>

    The problem that I have with this test is all the noise on lines 16-17.  I would rather reveal this intention through some well-named variables.

    A Belated Introduction


    My name is Eric Anderson, and I am NOT the newest member of LosTechies.  I am, however, the most recent person to make an introductory post. I landed my first development job in 1997 and stayed with that company through my graduation from Texas A&M University in 2000.  I took a break from software to pursue other interests from 2001 to 2006.  One of the first people that I met when returning to the industry in 2006 was fellow LosTechie Jimmy Bogard.  Since that time, I have come to appreciate Agile development practices and love to share the Agile love with those around me.

    I am honored to have been invited into the LosTechies fold, and I look forward to getting back to blogging and contributing to the software community at large.

subscribe via RSS