• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)


Date: Thursday, 09 Apr 2009 05:41

National Public Radio (NPR) is changing what it means to be a news organization. While traditional news organizations want to keep their content close, NPR has taken the approach of making content widely available via an API – an approach they call "brand and release." They've made 250,000 stories, going back 13 years, available through their API.

Zack Brand from NPR said that the NPR API is getting about 2 million requests per month, and there are 1,300 registrants (you have to register to get access to the API). Content is available in a variety of formats; so far, 51% of requests use XML, 20% RSS, and 23% widgets.

(Another notable new organization that has been making some content available via an API is the New York Times, which has an article search API, among others.)

Also participating in this session was Robin Sloan from Current.tv. Current made interesting use of Twitter streams as part of its presidential debate coverage. The hash tag they created for people to tag their posts, #current, was the third most popular Twitter tag during the debates, bested only by the tags for the candidates themselves.

Current built an application to provide a mash up of various data sources, including Digg, on election day. In true agile fashion, they made multiple software updates even after the show began broadcasting!

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 09 Apr 2009 05:39

Ben Galbraith and Dio Almaer of Ajaxian and the developer tools group at Mozilla gave a wide-ranging talk on web developer tools. They noted that the web often seems more like a hack than a platform — it's amazing that developers are able to make web apps do the things they do. This is especially true with Ajax raising the bar for interactivity, and sites turning into applications instead of documents. They're out to make the web a better platform.

Some future technologies that have them excited:

  • HTML5 canvas
  • Fast JavaScript — kicked off by Chrome, Firefox's TraceMonkey
  • Web workers, giving web apps the ability to have background threads
  • Desktop integration, such as Fluid, Prism, Adobe Air, and Titanium

As part of its efforts to improve the web as a platform, Mozilla is working on an open web tools directory, as well as a variety of development projects.

Ben and Dio noted that Firebug blew away existing tools and set a new standard for web development tools, providing a comprehensive set of tools in the browser itself. Other browsers have followed with IE8 and Safari 3.0 both providing good tools.

Mozilla Labs has a relatively new project called Bespin, a web-based code editor that is intended to be a showcase for HTML 5. This project is still young, and it won't run on an flavor of IE for a while, but it looks very promising.

Mozilla Labs is also working on a grid-based layout system using JavaScript and HTML5 canvas; so far, there's not much on the web site about this project, but an announcement is due soon.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 09 Apr 2009 04:32

The conference sessions at Web 2.0 Expo had a major emphasis on social media. I only attended a couple of these talks, about which I have brief comments below; at the end of the article, I have links to several others.

Social Media Marketing - why it fails and how to fix it

This one felt somewhat remedial to me, with the essential points being:

  • Be authentic. You need to be a person, not just a representative of a company.
  • It's hard to change the marketing culture in an organization to deal well with social media. (A point that I was glad to gloss over, being in my tiny organization that doesn't have this sort of problem.)
  • It's a conversation. (If in doubt, go read The Cluetrain Manifesto.)

The Whuffie Factor

Taking a completely different approach to similar material, Tara Hunt gave what I found to be the most inspiring and engaging talk of the conference: The Whuffie Factor.

Since both the slides and the video have been posted, I'll let her speak for herself.

Slides

Video


The Whuffie Factor: The 5 Keys for Maxing Social Capital and Winning with Online Communities (Tara Hunt) from Steffan Antonas on Vimeo.

Other Social Media Talks

Designing Social Interfaces

Designing Social Websites

Building Sites Around Social Objects


Building Sites Around Social Objects (Web 2.0 Expo - Jyri Engestrom, Google) from Steffan Antonas on Vimeo.

Social Media Buyer's Guide

Beyond Buzz: Measuring a Conversation

Author: "--"
Send by mail Print  Save  Delicious 
Date: Monday, 06 Apr 2009 22:02

March 31 - April 3, San Francisco

Last week's Web 2.0 Expo seemed like a successful event, with a good-sized crowd despite the economic malaise – due in part, no doubt, to unusually aggressive discounting and promotion. With multiple tracks across four days (one day of workshops and three of conference sessions) there was much more to see than any one person could possibly attend.

Here's a few articles that we've written about talks at the conference:

Many of the presentations are available online, as slides and/or videos:

And to go beyond the presentations and get more flavor of the event:

Author: "--"
Send by mail Print  Save  Delicious 
Date: Wednesday, 27 Aug 2008 20:21

Rails’ routing infrastructure supports the concept of conditional routes: preconditions that must be satisfied before a particular route will trigger. Rails 2.1 supports one built-in condition, HTTP method checking, which is of some use but rather limited. What I needed was to be able to limit certain routes to only trigger when a particular host-name was used to access the application.

I thought I’d have to write messy additional logic until a little comment tucked away in ActionController::Routing::RouteSet and ActionController::Routing::Routing caught my eye. Here I briefly show you how to leverage this functionality for your own purposes.

The Goal — Conditional Routes in routes.rb

Let’s work backwards and see the result I was aiming for. I wanted to expand the existing capabilities of the routing engine and be able to restrict routes to specific hosts. The conditional routing option works by adding a parameter to your route specifications. Here are some examples:

map.with_options(:controller => 'feeds', :conditions => {:hosts => MY_HOSTS}) do |feed|
  feed.feeds_articles '/feeds/articles', :action => 'articles'
  feed.feeds_podcast '/feeds/podcast', :action => 'podcast'
end

or

map.resources :podcasts, :conditions => {:hosts => MY_HOSTS}, 
   :member => {:show_notes => :get, :transcript => :get},
   :collection => {:admin => :get} do |podcast|
     podcast.resources :comments, :member => {:report_as_ham => :get, :report_as_spam => :get}
   end

or even

map.connect ':controller/:action/:id', :conditions => {:hosts => MY_HOSTS}

In Rails 2.1, however, no such option :hosts exists, only an option to check the HTTP method via :method.

The Implementation

I haven’t really ever needed to use the conditional routing support before, and didn’t really think about it due to it only supporting the HTTP method check. For that reason, I originally thought I’d have to write my own logic, either patching existing Routing routines (nearly right!) or by writing new stuff that could get messy (bad idea).

During a last scan through the code for the keyword “conditions”, I saw this comment:

# Plugins may override this method to add other conditions, like checks on
# host, subdomain, and so forth. Note that changes here only affect route
# recognition, not generation.

Good, a place to start afterall! The solution is elegant as it only requires overriding two simple routines. You can do this in your own app by writing code that gets loaded at startup. Here is one implementation in its entirety:

require 'action_controller'

module ActionController
  module Routing
    class RouteSet
      def extract_request_environment(request)
        { :method => request.method, :host => request.host }
      end
    end

    class Route
      def recognition_conditions
        result = ["(match = #{Regexp.new(recognition_pattern).inspect}.match(path))"]
        result << "conditions[:method] === env[:method]" if conditions[:method]
        result << "conditions[:hosts].include?(env[:host])" if conditions[:hosts]
        result
      end
    end
  end
end	

My code is very simplistic and tuned for my needs, but gives you an example of where to patch in. Here, I simply supply a list of host names I care about, and check the incoming host against that list.

Use extract_request_environment to parse out and store any data you will want to use in your conditional checks. This data will be available in the env hash later on.

recognition_conditions generates an Array of String objects that contain the Ruby code that will be used to build dynamic conditional test methods when the routing engine compiles the routes data in routes.rb.

I drop the source file into my project’s pre-existing lib/plugins/action_controller_extensions/lib directory as action_controller_extensions.rb and include an init.rb loader stub in my lib/plugins/action_controller_extensions directory:

require 'action_controller_extensions'	

My app deals with loading up such “plugins” at startup. You may have a different set-up. You can get the same effect by putting a require for the main source file in your startup code.

It would be great to see other generally useful conditionals contributed by the community.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

I feel lucky to have been able to attend last week’s Startup Camp and Foo Camp. These are unusual, invitation-only events, with extraordinary collections of people. Getting an invitation requires some mix of accomplishment, connections, and luck.

They are exclusive events not for the sake of exclusivity, but because they only work at a limited size. O’Reilly Media, which hosts the events and foots the bill (there’s no registration fee), gets to pick the attendees from its diverse range of colleagues and contacts.

Startup Camp

This was the first-ever Startup Camp, created by O’Reilly’s venture fund, O’Reilly Alpha Tech Ventures. OATV set up a two-day program, with a variety of startup veterans to give talks and lead discussions, and invited startups to apply. We were fortunate to be one of the 7 startups accepted — doubly so because getting into Startup Camp provided a much-sought-after invitation to Foo Camp as well.

The companies invited to Startup Camp spanned an incredibly broad range, from custom jewelry for tweens (WhirlyBelle from Replicator) to open-source server management software (Puppet from Reductive Labs) and open-source synthetic biology (Ginkgo BioWorks).

The presenters included Tim O’Reilly and Dale Dougherty (O’Reilly), Bryce Roberts (OATV), Esther Dyson, Evan Williams (Blogger, Twitter), Marc Hedlund (Wesabe), Michael Arrington (TechCrunch), Mark Fletcher (Bloglines), Dave McClure (500 Hats), Howard Morgan (First Round Capital), and Kathy Sierra (Creating Passionate Users).

Since this was an off-the-record session, you won’t see much reporting of the content, and I can’t add much to that either. Keep it in mind next summer if you find yourself leading a new startup and want to apply.

Dave McClure’s Startup Metrics for Pirates presentation is one talk whose slides have been made public. And the “Entrepreneurial Proverbs” session was inspired by older blog posts by the two presenters, Evan Williams and Marc Hedlund.

Foo Camp

As exciting as Startup Camp was, it was a prelude to the much larger Foo Camp.

Foo Camp was created by Tim O’Reilly and his colleague Sara Winge in 2003, and John Battelle wrote one of the first articles about it. The name nominally stands for Friends Of O’Reilly, and it is also a play on the use of “foo” as a stand-in variable name in programming examples (a practice that, incidentally, dates back to the 1960’s). Tim wrote about why Foo Camp last year.

The business rationale for Foo Camp is that it gives the O’Reilly team the opportunity to talk with hundreds of leading-edge thinkers, as they look for ideas for books and conferences.

There’s actually camping at Foo Camp: while many attendees stay at local hotels, a lot of them camp on the back lawn, and inside the office buildings, at O’Reilly. (For me, it’s only a five-minute drive, since O’Reilly is in my home town of Sebastopol, CA.)

O’Reilly aims to have about 250 people at Foo Camp, which requires turning away a lot of past attendees so they can invite lots of new people each year.

Among the well-known entrepreneurs and technologists attending this year were Jimmy Wales, Joshua Schacter, Steven Souders, Adrian Holovaty, Tom Coates, Scott Berkun, Ze Frank, Dries Buytaert, and Caterina Fake. That’s just a random selection of the better known names. There were dozens of other well-known folks, and dozens more inspired, creative folks who have lower profiles.

Most of O’Reilly’s editors and conference directors were there, as well as many of its authors. OATV’s portfolio companies were also well represented.

Foo Camp popularized the “unconference” format, in which the attendees create the program. The sponsors provide a chart with a grid of rooms and meeting times, and the attendees fill it in as they desire.

The unconference format is best known from the proliferation of Bar Camps, which were inspired by the early Foo Camps. (More geek humor here, as in foobar.)

When this format was new, people were often hesitant to propose sessions, but no longer. The schedule board was 80% full within minutes. There’s so many parallel tracks, and so many fascinating people, that you can only see a fraction of what goes on and meet a scattering of people.

One of my favorite sessions was on The Future of News. Both news, as journalism, and newspapers, as businesses, are in a period of dramatic change and stress. Presenters included Monica Guzman of the Seattle Post-Intelligencer, John Markoff and Nick Bilton from the New York Times, Steven Levy from NewsWeek, and Carl Malamud.

Other interesting sessions I joined covered topics including ubiquitous computing, curation vs. crowd-sourcing, pragmatic thinking and learning (Andy Hunt), personal genomics (Esther Dyson, 23andMe), and aggregation vs. copyright.

Tim O’Reilly debated Michael Arrington on whether it is important for Microsoft to develop its own search technology, or if getting it from Yahoo is a reasonable strategy. Danny Sullivan moderated. And yes, that is an inflatable elephant.

Here’s the pair of blog posts that inspired this session:

Retrospection

I have no doubt that this event serves O’Reilly well, but it nevertheless is a great contribution to the community. Rarely is such a diverse collection of extraordinary people brought together under such casual, low-pressure surroundings.

Looking back on Foo Camp, there are so many people I wish I had been able to spend time with, and sessions I wish I had attended. I’ll just have to hope for another invitation in years to come.

As someone who spent a decade running conferences, I at first found the unconference format unsettling. The completely self-organizing nature of the event means that its quality is determined entirely by the attendees. But with a crowd like this one, that’s a good thing.

More Foo Stuff

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

There’s a variety of screencasts and podcasts available for Ruby on Rails developers. Here’s a quick rundown of the major ones, and how they differ.

Podcasts

Audio podcasts are great for listening on the go, and for things such as news and interviews.

Tutorial: Learning Rails

Our own Learning Rails series consists of 8 podcasts that cover the fundamental concepts behind Ruby on Rails.

People: Ruby on Rails Podcast

The longest-running podcast in the Rails world is the “official” Ruby on Rails podcast, first created by Scott Barron but produced for most of its life by Geoffrey Grosenbach. This is a great series of interviews with many of the leading developers in the Ruby and Rails world.

News: Rails Envy

The Rails Envy podcast comes out every week and provides a fantastic summary of the latest developments in the Rails world. It’s put together by Gregg Pollack, Jason Seifer, and Steven Bristol, who diligently track a wide variety of Rails blogs to provide you with a distilled and entertaining weekly update.

Screencasts

Screencasts let you watch what’s going on on the screen while the presenter explains what they’re doing. It’s like looking over the shoulder of a developer while they work. Screencasts are a great teaching tool.

Learning Rails

Our Learning Rails screencast series shows how to build a simple web site using Ruby on Rails, step-by-step. Designed for people who are new to Ruby on Rails.

Envycasts

Envycasts is the latest entrant into the Rails screencasts business. They’re created by the Rails Envy folks, Gregg Pollack and Jason Seifer, who bring their trademark wit and creative production to advanced technical screencasts. There’s nothing else like them. Priced at $9 each.

Railscasts

Ryan Bates has producing more than 100 free Railscasts screencasts. They’re short episodes focused on a single feature of Rails, and are a great way to learn how to do specific things with Rails.

Peepcode

Geoffrey Grosenbach’s Peepcode are the gold standard for Ruby on Rails screencasts. At $9 each, they aren’t free, but they’re still a great value. They’re typically about an hour long and deeply explore specific topics, from Git to rSpec.

Pragmatic Screencasts

The Pragmatic Programmer, well known for their Ruby and Rails books, has teamed with Mike Clark of Pragmatic Studio, a leading provider of Rails training, to produce the Pragmatic Screencasts. The 20 to 30 minutes screencasts cost $5 each. So far, most of them are not about Ruby or Rails, but there is a series by Ryan Bates on “Everyday Active Record.”

RubyPlus

Bala Paranj has produce more than 70 free screencasts on various Ruby and Ruby on Rails techniques at RubyPlus.org.

Coderpath

Miles K. Forrest recorded a few early Rails screencasts at coderpath a couple years ago. He’s been quiet since, but he’s talking about restarting the series.

Zenunit Sensei

A short series of Rails screencasts, free for now with some talk of paid screencasts in the future, at Zenunit Sensei. From Australia, apparently by Julian Leviston.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

John Straw, chief software architect at YellowPages.com, gave an excellent talk at RailsConf about YellowPages’ conversion to Rails. We’ve pointed to YellowPages in the past as being one of the highest-traffic Rails sites, proving that Rails can scale.

John’s talk covered the scaling issues, but the talk was just as much about the process of successfully doing a big rewrite of a critical application at a large company. (YellowPages.com is part of AT&T.)

You can download John’s presentation from the RailsConf site.

With 2.5M searches per day and more than 170 million page views per month, YellowPages.com is now the biggest site AT&T runs, generating more traffic than att.com.

Why the rewrite?

The previous version was written in Java in 2004 and 2005 by consultants, and had fundamental design problems. This version had 125K lines of code and no automated tests, making new features hard to implement. The Rails version ended up with fewer than 20K lines of code, including tests.

The Java site also had lots of usability issues and SEO problems. As an example of the difficulty of adding features, John noted that it took three months to add a rating feature.

The requirements for the new version included:

  • Absolute control of URLs
  • No sessions
  • Be agile
  • Develop easy-to-leverage core business services

The new product was built by a cross-functional team of 20 people, including project managers, user experience experts, advertising people, search experts, and content and community managers. There were never more than 5 developers. The entire team sat together for the duration of the project.

The architecture they designed has three tiers: a web tier that delivers the front-end web experience; a services tier that responds to requests from the web tier; and a search cluster that performs the actual searches.

The team built an initial Rails prototype in early 2007 that looked like the existing site, just to get some experience with Rails. (Only one of the team members had any prior Rails experience.) They also built prototype search code in Python. They then started a new Rails prototype with designs from user experience team. They also built a Django prototype to explore that option, and evaluated EJB3/JBoss as a service tier platform.

Why Rails?

The team rejected Java for the front end in part because of its inadequate URL control. In terms of Rails vs. Django, John called the decision a near toss-up. Platform maturity was an important attribute that led them to choose Rails. They also felt that it had better automated testing integration and a clearer path to moving parts of it to C if necessary for performance. Ultimately, the development team simply felt more comfortable with it.

John had initially expected they would use Java for the service tier, but after an evaluation of EJB3 the team felt there were no real advantages over Ruby or Python for their application. All the reasons for choosing Rails for the web tier applied equally to service tier, and having a single software environment has obvious advantages.

Keeping the project moving

The success of this rewrite had as much to do with adeptly managing the process as with technology. One key to keeping it moving was giving one person decision-making authority. Another important factor was freezing development on the existing site, so they wouldn’t have a moving target. An ad-hoc rule they came up with was that if you can’t figure out quickly how you’d like to change something about the existing site, then don’t change it.

Another important process was early and frequent communication with the sales team. A previous site redesign had nearly failed because of lack of support from sales. The project lead, who came from the user experience team, met with 20 to 40 salespeople a week to review the proposed changes. This gave them the buy-in they needed for the site to be successful from a business perspective.

The site was made available to friends and family as a closed beta on 4/26/07, an open beta on 5/17/07, and then went live at the end of June, less than six months after beginning work on their first Rails prototype. This was the first time AT&T had released a beta of any kind.

A few things were farmed out to other teams, including HTML/CSS coding, rewrite rules for legacy URL translation, and performance evaluation for the production deployment configuration.

System architecture

The web tier, service tier, and search cluster are each fronted by an F5 load balancer. The web tier initially used Apache with 16 Mongrels on each server, while the service tier uses Apache with 30 Mongrels and memcached on each server.

The communication between tiers uses stateless HTTP transactions. The service tier provides a set of RESTful services that return JSON to the web tier. The search cluster uses the FAST ESP search engine.

The entire system consists of 25 machines, each with two dual-core, 64-bit processors. Two of the 25 are used for the database. This compares to 21 servers for the previous Java-based solution. There are two data centers with identical setups; each is designed to handle the entire load, so they provide geographically distributed redundancy.

They run Solaris on the database machines and CentOS 5 on all the others. John called Solaris “a mistake they wouldn’t repeat,” not because of any particular problems with it but because of a lack of system administrators in their organization who had experience with it.

They use Oracle for the database engine, which had issues with the large numbers of connections created by the large number of Mongrels. As a result, memory usage on the database servers was high, and these machines were upgraded to 12G of RAM.

Performance optimization

The performance goals, which were achieved, were:

  • Sub-second home page load time
  • 4-second average search time
  • Never dies

In the course of performance optimization, they considered HAProxy and Swiftiply but chose to go with the F5 because they had the hardware and understood how to use it.

They wrote Mongrel handlers to pick requests off from the web tier and send them to the service tier without involving Rails. They also wrote a C library for parsing search cluster responses and turning them into hashes.

In the web tier, they switched to Erubis for rendering views. They found asset download times to be a bigger issue than the speed of the framework. Following the Yahoo performance guidelines, they minified the JavaScript. They also switched from Prototype to jQuery.

They used the asset_packager plug-in (now made obsolete by Rails 2) and moved image serving to an Akamai edge cache.

They found that Apache was slow serving the 42-byte single-pixel GIFs that they use as analytics tags, which drove a shift to Nginx for the web tier.

After this tuning, performance was better than the Java site. In terms of availability, all site availability issues in first six months were due to database problems.

All things considered, it was a very successful rewrite. While the problems with the prior Java site cannot all be blamed on the technology, it is clear that Rails gave the team significant advantages with no loss of performance.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

In 2007, more than a dozen Ruby on Rails books debuted — only to be almost instantly made out-of-date by the release of Rails 2 toward the end of the year. In many respects, books written for Rails 1.2 are usable with Rails 2.0, but they can be problematic. If they use the scaffold generator in their examples, or dynamic scaffolding, the examples simply won’t work as written. And there are many small ways, such as the enhanced syntax for migrations, in which a Rails 1.2 book will teach a way that works, but is no longer optimal.

There are now some great Rails 2.0 books out, making life a lot easier for new and experienced Ruby on Rails programmers. Here’s a quick rundown of the recent books.

For Beginners

If you’re new to Rails and don’t have a lot of programming experience, Patrick Lenz’s Simply Rails 2 provides a great start. It explains all the concepts clearly and doesn’t assume much software development background. The example site built throughout the book is a Digg clone, which serves well to illustrate all the key topics.

Getting Started with Rails, for Experienced Developers

If you have some web application and object-oriented programming experience, then you may want a book that goes deeper and explains things more fully, but doesn’t take time to explain programming basics. Agile Web Development with Rails, which was for some time the only Rails book, is a great book for developers with some experience.

The second edition of this book, which is the newest available in print, is based on Rails 1.2, and the nicely detailed “Depot” shopping-cart example fails under Rails 2.0. The depth of this book also creates many places where the differences between the versions is significant.

Fortunately, the third edition is now available as a beta book. You can download today’s version as a PDF file, in which most of the critical updates have already been made, which comes with frequent updates, and also pre-order a printed copy so you’ll have one as soon it comes out the fall.

Going Deeper

After a slew of tutorial books in 2007, most of which are written for Rails 1.2, there’s been a recent surge in deeper, more advanced books that add a tremendous richness to the available Rails books.

The Rails Way is great reference work for Rails developers. It is not a book to start with, but it’s one I’d want to have by my side for reference once I had my bearings.

Advanced Rails Recipes includes dozens of short, focused articles explaining how to accomplish a particular Rails task. There’s a tremendous amount of accumulated community knowledge in this book, which was written by Mike Clark with contributions from many people in the community.

Practical REST on Rails 2 Projects, by Ben Scofield, is the first book to deeply explore the use of RESTful web services as implemented in Rails 2. It even includes an example of a Facebook application.

Deploying Rails Applications is the first book to really tackle Rails deployment in all of its complexities. With a cast of authors that includes Ezra Zygmuntowicz, Bruce Tate, Clinton Begin, Geoffrey Grosenbach, and Brian Hogan, this book encapsulates a lot of hard-earned knowledge and will save a lot of people a lot of pain.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

In his keynote talk at the recent Silicon Valley Ruby Conference, Sun’s Tim Bray asserted that PHP and Ruby are the languages of choice for new web apps.” Coming from most people, this wouldn’t be a remarkable comment, but given that Tim is Sun’s director of web technologies, it is worthy of note. Java wasn’t even on Tim’s list, much less his recommended solution.

Tim raised two major concerns about PHP: security and maintainability. He also pointed out that the object-oriented features “seem bolted on,” and don’t feel right as compared to Ruby. He did note that there are some great PHP applications, such as MediaWiki, WordPress, and Drupal.

Tim asserted that Rails is ahead of Java in terms of maintainability because you have so much less code. And, of course, Rails is best for time to market, which can be all-important to the success of a project.

As for when to avoid Rails, Tim cited these situations:

  • If the IT group will only deploy Java or .NET
  • When you need a lot of experienced developers quickly
  • If you have a complex database schema you don’t control
  • For an application that does a lot of computation

Tim asserted that “waterfall development just doesn’t work any more.” Some principles for success he cited:

  • Be human
  • Update often
  • Link
  • Don’t try to be sticky
  • Look good
  • Balance hubris and humility
  • Free the conversation

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

Last week’s Web 2.0 Expo had an overwhelming amount of content. Like any large conference, the quality was uneven, but there were some great talks and a lot of good ones. Among the main-session talks, Clay Shirky gave a wonderful talk on the implications of the web. I especially liked his view on the “cognitive surplus” created by the shift from rural to urban lifestyles, and how this has historically been consumed by alcohol, and then by television. Now this cognitive surplus fuels wikipedia, and all the other forms of user participation on the web. Where does the time come from? Just a fraction of the time spent watching television.

I’m halfway through his new book, Here Comes Everybody: The Power of Organizing without Organizations, and it promises to be a worthwhile read.

The most entertaining talk of the conference, by a long shot, was from Fake Steve Jobs, also known as Dan Lyons in his day job at Forbes. The Secret Diary of Steve Jobs is one of the best pieces of technology satire around.

Videos of all the other keynote presentations are also available.

Among the most technical talks, and the only one with any real Ruby on Rails content, was Gregg Pollack’s excellent talk on The Art of Testing Web Applications. (We proposed several Rails-related talks, but they didn’t make the cut; apparently the organizers chose to avoid most technology-specific talks this year.)

Many of the presentation files have been posted, and more are likely to be added soon.

Here’s an assortment of random factoids from my notes:

  • 70% of current.com users are on their computer at the same time they’re watching TV
  • There’s 2.43 billion photos on flickr
  • 28 million people a month share a video on YouTube
  • MySQL is downloaded 70,000 times a day
  • AIM stats:
    • Delivers 2 billion instant messages every day
    • Has had as many as 14 million simultaneous users
    • AIM sees a usage drop when there’s a popular show on TV, and then a peak when it ends
  • Ning stats:
    • Ning has about 250,000 individual social networks
    • 70% of the networks are active (used in last 30 days)
    • Adding 1 million registered users per month
    • Adding 1,500 new networks a day
  • MySpace stats:
    • 117M unique users last month
    • 100 billion rows of data in the database
    • 85 gigs of bandwidth
    • 5 million concurrent users
    • 200K to 400K new users per day
    • 11% of all on-line minutes are spent on myspace
    • 50 million messages sent per day
  • WordPress stats:
    • 54 million unique visitors in the U.S. each month — one in four people
    • 99.999% of WordPress blogs receive under 10,000 pageviews a day
    • In aggregate, there are 10+ million pageviews a day to permalink pages (45% of traffic)
    • An amount of content equivalent to 1.5 wikipedias is created on WordPress each month
Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

At the recent Silicon Valley Ruby Conference, Friends for Sale developer Alex Le outlined the approach they’ve taken to scaling up to deliver an impressive 300 million page views per month for their Rails-based Facebook application.

Friends for Sale is currently the #6 most popular application on Facebook. The application describes itself as follows:

“Buy and sell your friends as pets! You can make your pets poke, send gifts, or just show off for you. Make money as a shrewd pets investor or as a hot commodity!”

So I guess I there’s something here I don’t quite get — but in any case it has become perhaps the highest-traffic Rails app, delivering at least 50% more page views per month than yellowpages.com.

The app was created by the ironically named Serious Business Inc. The initial version was built in 10 days by Alex Le and Siqi Chen, using the RFacebook gem, and was launched on 11/1/07. Alex had previously worked on the rebuilding of yellowpages.com as a Rails application.

Referring to the oft-cited scaling aphorism, Alex asserted “Don’t scale until you need to… unless you’re on Facebook!” They had scalability problems on their first day because of the speed at which the audience ramped up. By the end of the first month they were delivering 1 million page views per day; by the end of the third month, they hit 10 million per day. They currently have 7 million users and 650,000 unique visitors per day.

Scaling to this traffic level required both adding lots of servers and tuning the database. They started out at Slicehost, and switched to SoftLayer when they needed more servers. Their decision to use SoftLayer was driven, in part, by the speed with which they could get them set up — 2 hours. Alex encouraged everyone to start with a hosting provider that can scale with you, to reduce the pain when traffic grows.

After two months, they hired a database administrator to handle the database tuning. Alex recommended using the Rails Query Analyzer plugin, and to index only the fields that you need to. He noted that while Active Record makes it easy to get the application going, it can get in the way when you need to optimize your database performance. They use Dr. Nic’s Magic Multi Connections plugin to handle the database connections, with some monkey-patching to fix issues they found; they plan to release their plugin code soon.

Their current server configuration includes:

  • One front-end server running nginx with fair for load balancing.
  • Eleven application servers, each with 8G RAM and four 2.4 GHz processors, running 16 Mongrel instances on each one (that’s 176 Mongrels!), with 4G on each server for memcached.
  • One master database server and three slaves, each with eight 2.3 GHz processors and 32G RAM, using 10K RPM SCSI drives in a Raid 1+0 configuration, running MySQL 5.

Their next step is to seek more performance from their existing hardware. Toward that end, they’re planning to move from fair to qrp (queueing reverse proxy) for load balancing, and they’re exploring alternative implementations of Mongrel that have faster threading models.

They also cache extensively. Serialized models are stored in memcached, using write-through caching. They moved logic to view helpers to simplify the use of fragment caching.

Serious Business has been recruiting for Rails developers, and in these ads they claim they are building the world’s largest Rails cluster. Maybe selling friends isn’t such a bad idea.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

This guide walks you through setup instructions for preparing a Windows Vista development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.

You will end up with a development machine with the following baseline components:

  1. Ruby and all basic Ruby utilities
  2. Ruby Gems package manager
  3. Subversion client
  4. MySQL database client utilities and server
  5. Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL
  6. SSH Terminal Program
  7. Git client (UPDATED)
  8. Programmer’s editor or IDE

Note: In the command sequences we illustrate here, command line prompts are shown as C:\>.

Prerequisites

This guide assumes you have a Windows computer running the current Windows Vista operating system with up-to-date service patches applied (SP1 or higher). It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.

You will need to have access to an Internet connection to complete various download steps.

You will need to have administrator access to your computer to complete this guide. Some of the Windows installers may ask you for your password. With most of the installer programs described below, Windows Vista will present the famous User Account Control (UAC) dialog asking whether an unidentified program should be permitted to have access to your computer.

You should select the “Allow” option which will let the specific installer program continue. In the specific case of MySQL, the MySQL installation process is not compatible with UAC. We will walk you through temporarily turning UAC off so you can install MySQL.

The Recipe

Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.

Ruby and Ruby Utilities (irb, ri, rdoc)

The One-Click Ruby Installer does a lot of work for you by installing Ruby, Ruby Gems Package Manager, Rake, all of the other standard Ruby tools, and even the open source SciTE programmer’s editor. Additionally, the installer configures the command line interface path information, so the Ruby tools are ready to use in the Command Prompt program.

Download the latest installer (1.8.6 r26 as of this writing) and double click on it to get started.

Select all of the default settings and let the installer complete its work. Once done, open a Command Prompt (aka DOS Command Line) window by selecting the Start menu, then enter cmd into the Start Search text box and pressing return.

You can check that Ruby is installed by typing the command:

  C:\> ruby -v
  ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

You should seem similar responses. If you get an unrecognized command error, try closing your Command Prompt window and opening another one.

Ruby Gems Package Manager

You next need to install the latest version of gem.

Check the version that gets installed:

  C:\> gem -v
  0.9.4

You need 1.0.1 or newer. If you have an older version, you can update with the command line: gem update --system.

Installing a Subversion client

Subversion will be used to access your source code repository during development and deployments. You will need a current version of the Subversion command line client and you can use the official Windows installers on subversion.tigris.org.

Download the latest “Windows installer with the basic win32 binaries” option on the site. Double click the setup program and select the default options.

Once the installer is done, open a new Command Prompt window and check the installation:

  C:\> svn --version
  svn, version 1.4.6 (r28521)
     compiled Dec 20 2007, 16:33:06
  ...

Installing MySQL via the Offical MySQL Installer

You will be installing MySQL via the official Windows Essentials installer from MySQL.com. This installer handles all of the setup steps for you.

NOTE: As of this writing, MySQL 5.0.51a and 5.1.23rc have bugs that prevent simple installation onto Vista. A workaround recipe is available but it is complicated. We recommend using a slightly older version, MySQL 5.0.45, as it doesn’t have the current installation bugs. We’ll update these instructions once fixes to the current MySQL line are available.

Unfortunately, the MySQL installer and Windows Vista User Account Control (UAC) conflict with one-another. You will have to temporarily turn UAC off.

First, go to the Start Menu, select Control Panel, and then click on User Accounts and Family Safety:

Click on the User Accounts link to open your account’s setting dialog:

Click on the Turn User Account Control on or off link. Assuming that User Account Control is still on, Windows Vista will ask for permission to continue with turning User Account Control off. Nice and circular, yes? Now you can actually turn UAC off. Unselect the checkbox and press OK.

You will be prompted to restart your computer. Go ahead and do so now.

One other change you will need to make is to open your Windows Vista Firewall to permit MySQL connections to the MySQL server port (3306). To do so, open Control Panel again, and select the Allow a program through Windows Firewall option of the Security group.

Press the Add port... button, and enter MySQL in the “Name:” field and 3306 in the “Port number:” field. Leave the protocol as “TCP”.

Press OK on the Windows Firewall Settings dialog box and close the Control Panel.

Finally, you can get on with installing MySQL. Double-click the community edition (open source) Windows Essentials MySQL setup program to get started:

Select the default (“Typical”) settings and location and let the program install itself. After it completes, a few ads will be shown, then a final dialog allowing you to configure the MySQL server. Make sure the check-box is selected and press “Finish”.

The “MySQL Server Instance Configuration Wizard” will run next. Choose the “Detailed Configuration” option and select all of the default choices. Doing so will configure the database to be running with settings best designed for a developer’s computer. When you get to the dialog offering the “Include Bin Directory in Windows PATH” option, we suggest you select it. If you don’t choose this option, you will need to manually set up your path so the “Command Prompt” program has easy access to MySQL client programs.

You will also be presented with a dialog to set a root password. If you are going to be working locally and aren’t worried about security, you can deselect “Modify Security Settings” and have a blank root password. We strongly suggest you set a password to be safe.

You can confirm that MySQL is running by trying to fire it up in the Command Prompt program:

  C:\> mysql -p -u root
  Enter password: ****
  Welcome to the MySQL monitor.  Commands end with ; or \g.
  Your MySQL connection id is 1
  Server version: 5.0.45-community-nt MySQL Community Edition (GPL)

  Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

  mysql> exit

When you reboot your computer, MySQL will start automatically in the future.

Once you have confirmed MySQL is working, you can also reverse the steps above for re-enabling User Account Control.

Gems

While the One-Click Ruby installer added some common Windows oriented gems for you, you still need the Ruby on Rails gems and the gems used in the LearningRails course. Install them with the command:

  C:\> gem install rails capistrano mongrel mongrel_cluster

All installed gems (including Ruby on Rails and its dependencies, Capistrano, Mongrel, and Mongrel_Cluster) will get installed at their latest versions.

The MySQL adapter gem needs to be installed next.

  C:\> gem install mysql

Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.

SSH Terminal Program

In deployment environments where your production or other remote servers are running a Unix-derived operating system, you will want to log in to those machines using the SSH protocol. A good Windows SSH terminal program is PuTTY. Download the complete Windows installer and double click to let it run.

You can select all of the default options. Once the installer finishes, you are good to login to your remote machines.

Installing a Git client

Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. The Git on MSys project team has done a nice job of building the git tools and a simple installer for Windows.

Download the latest installer (latest as of the last update of this article was Git-1.5.6.1-preview20080701.exe) and double click the executable.

During setup, you will be presented with a number of screens. Select the defaults until you get to the following two dialogs:

  1. “Adjust your PATH environment” dialog. Select the “Run Git from the Windows Command Prompt”.
  2. “Choosing the SSH executable” dialog. Select “Use PLink” since we just installed Putty.

The installer should complete, and you can optionally review the ReleaseNotes.rtf file.

The installer command places the core git tools and the man page documentation (type git help _commandname_ for help) on your machine and updates the PATH so you can use git from the Command Prompt. ruby script\plugin install should find git and use it for installation of newer plugins.

Note that if you have an older Rails project, you’ll want to update to Rails 2.1 or newer to get the latest support for git. When you upgrade, update your project with the rake rails:update command.

Code Editing Tools

While you can get by with using a plain text editor like Notepad you will have much high productivity if you use a programming editor that is highly tuned to Ruby on Rails development. The One-Click Ruby installer automatically installed the SciTE programmer’s editor. SciTE is ok for basic tasks with one or two files, but we recommend trying some of the other programs below.

We use the commercial TextMate programmer’s editor for much of our day to day work on the Macintosh. TextMate is highly extensible through a collection of community supplied “bundles”. There is a Windows “look-a-like/port” called the E Text Editor that looks promising and includes much of the functionality found on the Mac. Even better, it is supposed to be compatible with TextMate bundles, so as functionality improves for one platform, it should become available on the other. Worth trying the trial at the least.

There are a variety of good open source or free programmer editors available too. On the open source side you can find ports of vim and emacs, both of which have add-ons to create a full featured Ruby and Rails development tool set. jEdit is a very extensible open source editor written in Java that has a decent Ruby programming plugin set.

Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.

If you prefer an all-in-one tool, you should look at one of several integrated development environments that exist for Ruby. We use Netbeans in our LearningRails courses, but you should check out the numerous other options listed at BuildingWebApps.com.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

This guide walks you through setup instructions for preparing a Windows XP development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.

You will end up with a development machine with the following baseline components:

  1. Ruby and all basic Ruby utilities
  2. Ruby Gems package manager
  3. Subversion client
  4. MySQL database client utilities and server
  5. Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL
  6. SSH Terminal Program
  7. Git client (UPDATED)
  8. Programmer’s editor or IDE

Note: In the command sequences we illustrate here, command line prompts are shown as C:\>.

Prerequisites

This guide assumes you have a Windows computer running the current Windows XP operating system with up-to-date service patches applied (SP2 or higher). It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.

You will need to have access to an Internet connection to complete various download steps.

You will need to have administrator access to your computer to complete this guide. Some of the Windows installers may ask you for your password.

The Recipe

Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.

Ruby and Ruby Utilities (irb, ri, rdoc)

The One-Click Ruby Installer does a lot of work for you by installing Ruby, Ruby Gems Package Manager, Rake, all of the other standard Ruby tools, and even the open source SciTE programmer’s editor. Additionally, the installer configures the command line interface path information, so the Ruby tools are ready to use in the Command Prompt program.

Download the latest installer (1.8.6 r26 as of this writing) and double click on it to get started.

Select all of the default settings and let the installer complete its work. Once done, open a Command Prompt (aka DOS Command Line) window by selecting the Start menu, then the Run… menu item, and then typing cmd and pressing return.

You can check that Ruby is installed by typing the command:

  C:\> ruby -v
  ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

You should seem similar responses. If you get an unrecognized command error, try closing your Command Prompt window and opening another one.

Ruby Gems Package Manager

You next need to install the latest version of gem.

Check the version that gets installed:

  C:\> gem -v
  0.9.4

You need 1.0.1 or newer. If you have an older version, you can update with the command line: gem update --system.

Installing a Subversion client

Subversion will be used to access your source code repository during development and deployments. You will need a current version of the Subversion command line client and you can use the official Windows installers on subversion.tigris.org.

Download the latest “Windows installer with the basic win32 binaries” option on the site. Double click the setup program and select the default options.

Once the installer is done, open a new Command Prompt window and check the installation:

  C:\> svn --version
  svn, version 1.4.6 (r28521)
     compiled Dec 20 2007, 16:33:06
  ...

Installing MySQL via the Offical MySQL Installer

You will be installing MySQL via the official Windows Essentials installer from MySQL.com. This installer handles all of the setup steps for you. After downloading the community edition (open source) Windows Essentials setup program, double click it to start:

Select the default (“Typical”) settings and location and let the program install itself. After it completes, a few ads will be shown, then a final dialog allowing you to configure the MySQL server. Make sure the check-box is selected and press “Finish”.

The “MySQL Server Instance Configuration Wizard” will run next. Choose the “Detailed Configuration” option and select all of the default choices. Doing so will configure the database to be running with settings best designed for a developer’s computer. When you get to the dialog offering the “Include Bin Directory in Windows PATH” option, we suggest you select it. If you don’t choose this option, you will need to manually set up your path so the “Command Prompt” program has easy access to MySQL client programs.

You will also be presented with a dialog to set a root password. If you are going to be working locally and aren’t worried about security, you can deselect “Modify Security Settings” and have a blank root password. We strongly suggest you set a password to be safe.

You can confirm that MySQL is running by trying to fire it up in the Command Prompt program:

  C:\> mysql -p -u root
  Enter password: ****
  Welcome to the MySQL monitor.  Commands end with ; or \g.
  Your MySQL connection id is 1
  Server version: 5.0.51a-community-nt MySQL Community Edition (GPL)

  Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

  mysql> exit

When you reboot your computer, MySQL will start automatically in the future.

Gems

While the One-Click Ruby installer added some common Windows oriented gems for you, you still need the Ruby on Rails gems and the gems used in the LearningRails course. Install them with the command:

  C:\> gem install rails capistrano mongrel mongrel_cluster

All installed gems (including Ruby on Rails and its dependencies, Capistrano, Mongrel, and Mongrel_Cluster) will get installed at their latest versions.

The MySQL adapter gem needs to be installed next.

  C:\> gem install mysql

Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.

SSH Terminal Program

In deployment environments where your production or other remote servers are running a Unix-derived operating system, you will want to log in to those machines using the SSH protocol. A good Windows SSH terminal program is PuTTY. Download the complete Windows installer and double click to let it run.

You can select all of the default options. Once the installer finishes, you are ready to login to your remote machines.

Installing a Git client

Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. The Git on MSys project team has done a nice job of building the git tools and a simple installer for Windows.

Download the latest installer (latest as of the last update of this article was Git-1.5.6.1-preview20080701.exe) and double click the executable.

During setup, you will be presented with a number of screens. Select the defaults until you get to the following two dialogs:

  1. “Adjust your PATH environment” dialog. Select the “Run Git from the Windows Command Prompt”.
  2. “Choosing the SSH executable” dialog. Select “Use PLink” since we just installed Putty.

The installer should complete, and you can optionally review the ReleaseNotes.rtf file.

The installer command places the core git tools and the man page documentation (type git help _commandname_ for help) on your machine and updates the PATH so you can use git from the Command Prompt. ruby script\plugin install should find git and use it for installation of newer plugins.

Note that if you have an older Rails project, you’ll want to update to Rails 2.1 or newer to get the latest support for git. When you upgrade, update your project with the rake rails:update command.

Code Editing Tools

While you can get by with using a plain text editor like Notepad you will have much higher productivity if you use a programming editor that is highly tuned to Ruby on Rails development. The One-Click Ruby installer automatically installed the SciTE programmer’s editor. SciTE is ok for basic tasks with one or two files, but we recommend trying some of the other programs below.

We use the commercial TextMate programmer’s editor for much of our day to day work on the Macintosh. TextMate is highly extensible through a collection of community supplied “bundles”. There is a Windows “look-a-like/port” called the E Text Editor that looks promising and includes much of the functionality found on the Mac. Even better, it is supposed to be compatible with TextMate bundles, so as functionality improves for one platform, it should become available on the other. There is a trial version available if you want to test it out.

There are a variety of good open source or free programmer editors available too. On the open source side you can find ports of vim and emacs, both of which have add-ons to create a full featured Ruby and Rails development tool set. jEdit is a very extensible open source editor written in Java that has a decent Ruby programming plugin set.

Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.

If you prefer an all-in-one tool, you should look at one of several integrated development environments that exist for Ruby. We use Netbeans in our LearningRails courses, but you should check out the numerous other options listed at BuildingWebApps.com.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

This guide walks you through setup instructions for preparing a Mac OS X 10.4 (aka Tiger) development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.

You will end up with a development machine with the following baseline components:

  1. Ruby and all basic Ruby utilities
  2. Ruby Gems package manager
  3. Subversion client
  4. Git client
  5. Native development tools (Xcode, C compiler)
  6. MacPorts native code package manager
  7. MySQL database client utilities and server
  8. Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL
  9. Programmer’s editor or IDE

Note: In the command sequences we illustrate here, command line prompts are shown as a dollar sign ($).

Prerequisites

This guide assumes you have a Macintosh computer running the current Tiger operating system with up-to-date System Update patches applied. It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.

You will need to have access to an Internet connection to complete various download steps.

You will need to have administrator access to your computer to complete this guide. We will be using the sudo command to run various command line programs and some of the Mac OS X native installers will also ask you for your password.

It is helpful if you have access to your operating system installation discs.

The Recipe

Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.

If you are planning on upgrading to Mac OS X 10.5 (Leopard), you should do so now and save some time setting up the Ruby environment. Leopard comes with a current version of Ruby and it makes setting things up much easier. If you follow this guide and then upgrade to Leopard later, it is pretty simple to deactivate (or remove) the redundant components that are no longer needed.

Native Development Tools (X11 and Xcode 2.5)

MacPorts will use native development tools when installing many of the utilities listed in this guide. You will also need a native compiler to build many of the gems’ native libraries you are going to use. Apple provides a free native compiler tool set called Xcode. If you have your Tiger installation DVD, load it now. If you don’t have an installation DVD, you can download the Xcode 2.5 tools at Apple’s Developer Web Site. (Note: Apple developer accounts are free.)

Open the Xcode Tools folder (or DMG file if you downloaded the package). Double click on the XcodeTools.mpkg installer and select a standard install. This will take a few minutes to run:

As an optional step, some tools require that the X11 window manager application be installed. Under Tiger, this is an optional install. You can find X11 on your Tiger installation DVD or download it from Apple.

MacPorts

MacPorts is a native code package manager for Macintosh software. This guide uses MacPorts to setup the Ruby tools, MySQL, and the Git distributed version control system. There are many other tools available in the MacPorts library, so it is well worth checking out.

Download the Tiger Universal version (1.6.0 at the time of this writing) and double click the MacPorts DMG file to open it up. Double click on “MacPorts-1.6.0.pkg” to start the installer and select the default options.

After MacPorts completes installation, you need to adjust your command line PATH environment variable so you can run the port command.

Fire up the Terminal program and enter the command:

  $ open .bash_profile

Note that there is a period in front of “bash_profile”. The bash shell configuration file should open in the TextEdit program. If you don’t have a .bash_profile, you can create a new one in your text editor and save it in your home directory.

(By the way, we recommend iTerm as a nice open source replacement to the Apple Terminal program.)

Inside of .bash_profile, find the line that starts with export PATH=, if present. You are going to insert the new directories used by MacPorts into your path:

  export PATH="/opt/local/bin:/opt/local/sbin:$PATH"

If you don’t have a line that exports your PATH, use the text exactly as above. If you do already have such a line, add the /opt/local/bin:/opt/local/sbin: (note colons) after the first quote, but before any other paths. Here is an example:

  export PATH="/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:$PATH"

Save the file and close TextEdit. Open a new terminal window and have MacPorts update itself with the command:

  $ sudo port selfupdate

Ruby and Ruby Utilities (irb, ri, rdoc)

Tiger comes pre-installed with a version of Ruby that is out of date for day to day use. You will use MacPorts to upgrade to the latest production version of the Ruby toolset. In a terminal window type:

  $ sudo port install ruby
  Password:
  --->  Fetching ncursesw
  --->  Attempting to fetch ncurses-5.6.tar.gz from http://ftp.gnu.org/gnu/ncurses
  --->  Verifying checksum(s) for ncursesw
  --->  Extracting ncursesw
  --->  Applying patches to ncursesw
  --->  Configuring ncursesw
  --->  Building ncursesw with target all
  --->  Staging ncursesw into destroot
...
  --->  Installing ncurses 5.6_0+darwin_8
  --->  Activating ncurses 5.6_0+darwin_8
  --->  Cleaning ncurses
  --->  Fetching openssl
  --->  Attempting to fetch openssl-0.9.8e.tar.gz from http://www.openssl.org/source/
...
  --->  Fetching ruby
  --->  Attempting to fetch ruby-1.8.6.tar.gz from http://www.ibiblio.org/pub/languages/ruby/1.8
  --->  Attempting to fetch ruby-1.8.6.tar.gz from http://mirrors.sunsite.dk/ruby/1.8
  --->  Verifying checksum(s) for ruby
  --->  Extracting ruby
  --->  Applying patches to ruby
  --->  Configuring ruby
  --->  Building ruby with target all
  --->  Staging ruby into destroot
  --->  Packaging tgz archive for ruby 1.8.6_0+thread_hooks
  --->  Installing ruby 1.8.6_0+thread_hooks
  --->  Activating ruby 1.8.6_0+thread_hooks
  --->  Cleaning ruby

Your output may be slightly different depending on the versions of software at the time you run these commands. The listing here was edited for brevity.

You can check that Ruby is installed with:

  $ which ruby
  /opt/local/bin/ruby
  $ ruby -v
  ruby 1.8.6 (2007-03-13 patchlevel 0) [powerpc-darwin8.11]

You should seem similar responses. The important one is the first one which reports back the path of the program. If you are using the MacPorts Ruby, it will be located in /opt/local/bin/.

Ruby Gems Package Manager

You next need to install the latest version of gem.

  $ sudo port install rb-rubygems rb-termios

Check the version that gets installed:

  $ gem -v
  0.9.4

You need 1.0.1 or newer. If you have an older version, you can update with the command line: sudo gem update --system.

Installing a Subversion client

Subversion will be used to access your source code repository during development and deployments. You will need a current version of the Subversion client and you can use MacPorts to install it:

  $ sudo port install subversion +tools

Installing Git via MacPorts

Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. Currently Leopard doesn’t install git by default, so we’ll use MacPorts to quickly install git:

   $ sudo port install git-core +doc +svn

This command installs the core git tools, the man page documentation, and integration with Subversion. This last is useful if you plan on migrating from or need to work with a legacy Subversion repository. The installation will take a while; it has a lot to load.

Besides your own project version control, you’ll typically use git when loading Rails 2.1 and various 3rd party plugins.

Installing MySQL via MacPorts

By leveraging MacPorts to install MySQL, maintenance of the software is slightly easier, especially when you want to upgrade over time. We are using MySQL on our development machine as we prefer to have identical software across our environments. Rails 2.0.2, 2.1, and newer uses SQLite by default, which is fine for development and experimentation, but not appropriate for production code.

To get started, type into your terminal window:

  $ sudo port install mysql5 +server

This command downloads and installs the baseline MySQL client programs and server software. Next, you want to configure MySQL’s server so it launches when your computer boots up:

  $ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

launchctl is an Apple tool that administers the system daemon that controls the boot process and background programs. Here you are loading the instructions for how to manage MySQL.

A fresh MySQL installation requires its database storage area to be initialized, so you do that next:

  $ sudo mysql_install_db5 --user=mysql

When you configure the storage area with this command, you’re making sure it is owned by the user “mysql”.

MySQL creates a special system file used for program to program communication, called the “socket” file. By default, the MacPorts installation of MySQL server creates this in the directory “/opt/local/var/run/mysql5/mysqld.sock”. Ruby on Rails applications can deal with this just fine if you change the settings in your database.yml file to include a socket entry that points to the correct place. However, we are going to tweak things so all applications can find the file in a fairly standard place: /tmp/mysql.sock with little or no modification.

First, you need to move the default configuration file, my.cnf, to the correct place:

  $ sudo mv /opt/local/etc/my.cnf /opt/local/etc/mysql5/my.cnf

If the installation program didn’t put a file into /opt/local/etc/, try this instead:

  $ sudo mv /opt/local/share/mysql5/mysql/my-medium.cnf /opt/local/etc/mysql5/my.cnf

Now, you need to edit the configuration file to change where the socket file is stored:

  $ sudo pico /opt/local/etc/mysql5/my.cnf

If you aren’t familiar with the pico command line editor, we explain the few commands you will need here.

Inside of pico, use your arrow keys to move down to the line where you first see “[client]” and make the following changes (this is just a small part of the whole file):

  ...
  # In this file, you can use all long options that a program supports.
  # If you want to know which options a program supports, run the program
  # with the "--help" option.
  
  [mysqld_safe]
  socket          = /tmp/mysql.sock

  # The following options will be passed to all MySQL clients
  [client]
  #password       = your_password
  port            = 3306
  socket          = /tmp/mysql.sock

  # Here follows entries for some specific programs

  # The MySQL server
  [mysqld]
  port            = 3306
  socket          = /tmp/mysql.sock
  ...

You are adding the “[mysqld_safe]” section (2 lines) just above “[client]” and then changing the two instances of the "socket = " lines in the “[client]” and “[mysqld]” sections to be /tmp/mysql.sock. Once done, press Control-X, answer Y when asked to save, and press return to accept the default file name (“my.cnf”).

Now you start the server up manually:

  $ cd /opt/local ; sudo /opt/local/lib/mysql5/bin/mysqld_safe &   

You can confirm that MySQL is running by trying to fire it up:

  $ mysql5 -p -u root
  Welcome to the MySQL monitor.  Commands end with ; or \g.
  Your MySQL connection id is 1
  Server version: 5.0.45 Source distribution

  Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

  mysql> exit

When you reboot your computer, MySQL should start automatically in the future.

Gems

Tiger requires that you install the base collection of gems you will be using:

  $ sudo gem install rake rails capistrano mongrel mongrel_cluster

All installed gems (including Ruby on Rails and its dependencies, Rake, Capistrano, Mongrel, and Mongrel_Cluster) will get installed at their latest versions.

The MySQL adapter gem needs to be installed, and it is a little finicky due to our use of MacPorts.

If you are running Tiger on an Intel processor, use this command (on one line):

  $ ARCHFLAGS="-arch i386" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5

and if you are on a PowerPC processor, use this command:

  ARCHFLAGS="-arch ppc" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5

Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.

Code Editing Tools

While you can get by with using a plain text editor like TextEdit, or even Apples Xcode IDE, you will have much high productivity if you use a programming editor that is highly tuned to Ruby on Rails development.

We use the commercial TextMate programmer’s editor for much of our day to day work. TextMate is highly extensible through a collection of community supplied “bundles”. Many add-ons accelerate development by enhancing the editor (for example, adding language specific short cuts to reduce your typing) or by tying in to other utilities, such as Subversion or Rake, to allow you to quickly get tasks done without leaving the editor’s environment.

There are a variety of good open source or free programmer editors available too. On the open source side, Leopard comes pre-installed with both vim and emacs. jEdit is a very extensible open source editor written in Java. TextWrangler is a free programmer’s editor from BareBones.

Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.

If you prefer an all-in-one tool, you should look at one of several integrated development environments that exist for Ruby. We use Netbeans in our LearningRails courses, but you should check out the numerous other options listed at BuildingWebApps.com.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

This guide walks you through setup instructions for preparing a Mac OS X 10.5 (aka Leopard) development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.

You will end up with a development machine with the following baseline components:

  1. Ruby and all basic Ruby utilities
  2. Ruby Gems package manager
  3. Subversion client
  4. Git client
  5. Native development tools (Xcode, C compiler)
  6. MacPorts native code package manager
  7. MySQL database client utilities and server
  8. Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL
  9. Programmer’s editor or IDE

Note: In the command sequences we illustrate here, command line prompts are shown as a dollar sign ($).

Prerequisites

This guide assumes you have a Macintosh computer running the current Leopard operating system with up-to-date System Update patches applied. It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.

You will need to have access to an Internet connection to complete various download steps.

You will need to have administrator access to your computer to complete this guide. We will be using the sudo command to run various command line programs and some of the Mac OS X native installers will also ask you for your password.

It is helpful if you have access to your operating system installation discs.

The Recipe

Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.

Ruby and Ruby Utilities (irb, ri, rdoc)

Leopard comes pre-installed with Ruby 1.8.6 and its associated utilities. You can use these programs as is. To check them out, open a Terminal window and type:

  $ which ruby
  /usr/bin/ruby
  $ ruby -v
  ruby 1.8.6 (2007-09-24 patchlevel 111) [universal-darwin9.0]

You should seem similar responses. The important one is the first one which reports back the path of the Ruby interpreter program. If you are using the built-in Ruby, it will be located in /usr/bin/.

Ruby Gems Package Manager

Leopard comes with a pre-installed version of gem. Be sure you have the latest version:

  $ gem -v
  1.0.1

You need 1.0.1 or newer. If you have an older version, you can update with the command line: sudo gem update --system.

Native Development Tools (Xcode 3.0)

You will need a native compiler to build many of the gems’ native libraries you are going to use. You will also occasionally build other native tools via the MacPorts tool described below. Apple provides a free native compiler tool set called Xcode. If you have your Leopard installation DVD, load it now. If you don’t have an installation DVD, you can download the Xcode 3.0 tools at Apple’s Developer Web Site. (Note: Apple developer accounts are free.)

Open the Optional Installs folder, and then the Xcode Tools folder. Double click on the XcodeTools.mpkg installer and select a standard install. This will take a few minutes to run:

MacPorts

MacPorts is a native code package manager for Macintosh software. This guide uses MacPorts to setup an installation of MySQL and the Git distributed version control system. There are many other tools available in the MacPorts library, so it is well worth checking out.

Download the Leopard Universal version (1.6.0 at the time of this writing) and double click the MacPorts DMG file to open it up. Double click on “MacPorts-1.6.0.pkg” to start the installer and select the default options.

After MacPorts completes installation, you need to adjust your command line PATH environment variable so you can run the port command.

Fire up the Terminal program and enter the command:

  $ open .bash_profile

Note that there is a period in front of “bash_profile”. The bash shell configuration file should open in the TextEdit program. If you don’t have a .bash_profile, you can create a new one in your text editor and save it in your home directory.

(By the way, we recommend iTerm as a nice open source replacement for the Apple Terminal program.)

Inside of .bash_profile, find the line that starts with export PATH=, if present. You are going to insert the new directories used by MacPorts into your path:

  export PATH="/opt/local/bin:/opt/local/sbin:$PATH"

If you don’t have a line that exports your PATH, use the text exactly as above. If you do already have such a line, add the /opt/local/bin:/opt/local/sbin: (note colons) after the first quote, but before any other paths. Here is an example:

  export PATH="/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:$PATH"

Save the file and close TextEdit. Open a new terminal window and have MacPorts update itself with the command:

  $ sudo port selfupdate

Installing Git via MacPorts

Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. Currently Leopard doesn’t install git by default, so we’ll use MacPorts to quickly install git:

   $ sudo port install git-core +doc +svn

This command installs the core git tools, the man page documentation, and integration with Subversion. This last is useful if you plan on migrating from or need to work with a legacy Subversion repository. The installation will take a while; it has a lot to load.

Besides your own project version control, you’ll typically use git when loading Rails 2.1 and various 3rd party plugins.

Installing MySQL via MacPorts

By leveraging MacPorts to install MySQL, maintenance of the software is slightly easier, especially when you want to upgrade over time. We are using MySQL on our development machine as we prefer to have identical software across our environments. Rails 2.0.2, 2.1 and newer uses SQLite by default, which is fine for development and experimentation, but not appropriate for production code.

To get started, type into your terminal window:

  $ sudo port install mysql5 +server

This command downloads and installs the baseline MySQL client programs and server software. Next, you want to configure MySQL’s server so it launches when your computer boots up:

  $ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

launchctl is an Apple tool that administers the system daemon that controls the boot process and background programs. Here you are loading the instructions for how to manage MySQL.

A fresh MySQL installation requires its database storage area to be initialized, so you do that next:

  $ sudo mysql_install_db5 --user=mysql

When you configure the storage area with this command, you’re making sure it is owned by the user “mysql”.

MySQL creates a special system file used for program to program communication, called the “socket” file. By default, the MacPorts installation of MySQL server creates this in the directory “/opt/local/var/run/mysql5/mysqld.sock”. Ruby on Rails applications can deal with this just fine if you change the settings in your database.yml file to include a socket entry that points to the correct place. However, we are going to tweak things so all applications can find the file in a fairly standard place: /tmp/mysql.sock with little or no modification.

First, you need to move the default configuration file, my.cnf, to the correct place:

  $ sudo mv /opt/local/etc/my.cnf /opt/local/etc/mysql5/my.cnf

If the installation program didn’t put a file into /opt/local/etc/, try this instead:

  $ sudo mv /opt/local/share/mysql5/mysql/my-medium.cnf /opt/local/etc/mysql5/my.cnf

Now, you need to edit the configuration file to change where the socket file is stored:

  $ sudo pico /opt/local/etc/mysql5/my.cnf

If you aren’t familiar with the pico command line editor, we explain the few commands you will need here.

Inside of pico, use your arrow keys to move down to the line where you first see “[client]” and make the following changes (this is just a small part of the whole file):

  ...
  # In this file, you can use all long options that a program supports.
  # If you want to know which options a program supports, run the program
  # with the "--help" option.
  
  [mysqld_safe]
  socket          = /tmp/mysql.sock

  # The following options will be passed to all MySQL clients
  [client]
  #password       = your_password
  port            = 3306
  socket          = /tmp/mysql.sock

  # Here follows entries for some specific programs

  # The MySQL server
  [mysqld]
  port            = 3306
  socket          = /tmp/mysql.sock
  ...

You are adding the “[mysqld_safe]” section (2 lines) just above “[client]” and then changing the two instances of the "socket = " lines in the “[client]” and “[mysqld]” sections to be /tmp/mysql.sock. Once done, press Control-X, answer Y when asked to save, and press return to accept the default file name (“my.cnf”).

Now you start the server up manually:

  $ cd /opt/local ; sudo /opt/local/lib/mysql5/bin/mysqld_safe &   

You can confirm that MySQL is running by trying to fire it up:

  $ mysql5 -p -u root
  Welcome to the MySQL monitor.  Commands end with ; or \g.
  Your MySQL connection id is 1
  Server version: 5.0.45 Source distribution

  Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

  mysql> exit

When you reboot your computer, MySQL should start automatically in the future.

Gems

Leopard conveniently pre-installs the base collection of gems you will be using, but you need to make sure they are up to date:

  $ sudo gem update

All installed gems (including Ruby on Rails and its dependencies, Rake, Capistrano, Mongrel, and Mongrel_Cluster) will get updated.

The MySQL adapter gem needs to be installed, and it is a little finicky due to our use of MacPorts.

If you are running Leopard on an Intel processor, use this command (on one line):

  $ ARCHFLAGS="-arch i386" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5

and if you are on a PowerPC processor, use this command:

  ARCHFLAGS="-arch ppc" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5

Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.

Code Editing Tools

While you can get by with using a plain text editor like TextEdit, or even Apple’s Xcode IDE, you will be more productive if you use a programming editor that is highly tuned to Ruby on Rails development.

We use the commercial TextMate programmer’s editor for much of our day-to-day work. TextMate is highly extensible through a collection of community supplied “bundles”. Many add-ons accelerate development by enhancing the editor (for example, adding language specific short cuts to reduce your typing) or by tying in to other utilities, such as Subversion or Rake, to allow you to quickly get tasks done without leaving the editor’s environment.

There are a variety of good open source or free programmer editors available too. On the open source side, Leopard comes pre-installed with both vim and emacs. jEdit is a very extensible open source editor written in Java. TextWrangler is a free programmer’s editor from BareBones.

Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.

If you prefer an all-in-one tool, ook at one of the integrated development environments for Ruby. We use Netbeans when we aren’t using TextMate, but the numerous other options listed at BuildingWebApps.com are worth a look.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

Whenever I deploy a Rails site, I install the exception notification plugin so I get an email if a user provokes a bug I hadn’t found. It’s a piece of cake to install:

1. Install the plugin

ruby script/plugin install exception_notification

2. Include the plugin in your ApplicationController (in the application.rb file)

include ExceptionNotifiable

3. Add one line to your environment.rb file to specify where to send the email

ExceptionNotifier.exception_recipients = %w(person1@domain.com person2@domain.com)

4. Make sure you have ActionMailer configured (to use either sendmail or STMP), which you’ll already have done if your app sends email for any purpose.

What’s this? Errors already?

A few minutes after I first installed the Exception Notification plugin, I checked my inbox and found a dozen error emails from the site! After a brief moment of panic, I realized that all were coming from search engine spiders, and that the URLs were all invalid. I had replaced an old, crufty, static HTML site, and the spiders were rechecking pages they had indexed in the past.

So the next question was what to do with the old URLs. I could remap each URL to the most appropriate page on the new site, but the old site got little traffic and there wasn’t a clear mapping between the two sets of pages, so it hardly seemed worth it. I decided to map index.html to the new home page, since many people might have bookmarked that page, and it was clear what it should map to. As for everything else, I wanted a way to tell the spiders to stop trying to index them, and to tell anyone who accessed them that this was no longer a valid URL and they should explore the new site.

The heart of the fix is to add a few lines to routes.rb. Fortunately, the old site design had put all the HTML pages except for the index page into a directory called html. There were also some PDF files, conveniently in a directory named web_pdfs.

Here’s the routes, which I added at the end just before the default route:


map.connect '/index.html', :controller => 'page', :action => 'home'
map.connect '/html/*any', :controller => 'page', :action => 'oldpage'
map.connect '/web_pdfs/*any', :controller => 'page', :action => 'oldpage'

I have a controller called page_controller that manages the public parts of the site. The first route simply maps index.html to the home page action.

The second route maps any URL in the html directory to a new page, which I called simply “oldpage”. The oldpage.rhtml file simply has some text telling the visitor that this page no longer exists, and gives them some suggestions for exploring the new site.

The “*any” in the route definition absorbs whatever comes after “/html/”. With this technique, I don’t have to worry about whether there might be subdirectories within html, or what the file name extensions might be.

The final piece was to tell the spiders not to bother with these pages any more. I didn’t want to use a redirect, because the page to which I wanted to redirect the user wasn’t the new permanent page, but rather one that explained that the site had been changed. I decided to set the HTTP header to the “gone” status code (410). This just takes one line in the page controller oldpage action:


def oldpage
  render :template => 'page/oldpage', :status => :gone
end

Eventually the spiders will stop spidering these old pages, but since index.html will still lead to the new home page without any error code, they will find all the new pages from there.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

In any application in which a user enters an email address, there is the very real possibility that the user will make a typo and your application will end up with an invalid address. You can have them enter it twice, but this seems clunky. And you can, of course, send an email with an activation link, which provides the only true validation, but there’s no need to bother sending the email if you know the address is no good. Furthermore, once you’re past the page where the user enters their email address, you’ve missed your chance to tell them there’s something wrong and they should correct it.

So you really should do what you can to validate the address when the user enters it. I recently made a simple addition to my applications that helps a lot: verify that the domain name is valid.

It’s surprisingly easy to do — especially with a little help from Peter Cooper’s excellent Beginning Ruby, which has a very useful chapter on network programming. The following code is adapted from his examples:

require 'resolv'
def validate_email_domain(email)
      domain = email.match(/\@(.+)/)[1]
      Resolv::DNS.open do |dns|
          @mx = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
      end
      @mx.size > 0 ? true : false
end

This example makes use of the Ruby standard library “resolv”, so you need to require it first.

The first step is to separate the domain name from the rest of the email address. The regular expression captures the part of the string that follows the @ symbol.

Then the code creates a new DNS resolver object and queries the resolver for an MX (mail exchanger) resource at the specified domain. This returns an array, which will be empty if there is no MX record for the domain.

(Note: In a previous version of this article, I used Resolv.getaddress to see if there is a DNS entry for the domain, instead of checking for an MX record. This approach works most of the time, but it rejects any domain for which there is no A record. If a domain is used only for email and not for a web server, there might not be an A record. Also, some domains have an A record only for www.domain.com, which will also fail the simple getaddress test.)

You can use something like the following in the validate method within the appropriate model:

unless email.blank?
    unless email =~ /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/
        errors.add(:email, "Your email address does not appear to be valid")
    else
        errors.add(:email, "Your email domain name appears to be incorrect") unless validate_email_domain(email)
    end
end

I first check to make sure the email address is not blank, because that’s detected by a simple validates_presence_of :email statement that produces a different error message.

Then I make sure that the email address is at least syntactically reasonable, with a rather ugly regular expression, before bothering to check the DNS.

It should be noted that the regex I use here isn’t designed to cover all of the RFC2822 cases, nor with other RFC drafts dealing with non-ASCII addressing.

An even better approach would be to use an observer to validate the address with an Ajax call before the user submits the form.

It is possible to take this a step further by sending the SMTP server referenced in the MX record a “RCPT TO:” command. In theory, this would check that the user name is valid as well as the domain name. This takes additional time, however, and I’ve read that the response from mail servers is often not reliable. If anyone has tried this, I’d appreciate any feedback on how well it worked.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

With a basic SSH setup, you have to enter your password every time you log in to the server, which is not unreasonable from a security perspective. But if you want to automate tasks and use deployment tools such as Capistrano, you’ll end up typing that password over and over again, even for a single deployment process. Fortunately, there is a mechanism to avoid this while still preserving good security. But, as with most such things in Windows, it takes a little effort to set it up. (Things are a little simple on Macs, which we’ll cover in a future article.)

SSH authentication uses public key cryptography, in which you have a private key available only to you on your local system, and a matching public key that can be published on your server. Authentication software can confirm that the public and private keys match, but hackers cannot derive your private key from your public key. Once you set up a public-private key pair, these keys can be used to authenticate your SSH sessions, and you won’t ever have to type your password again.

There’s a couple different programs you can use to accomplish this; I’m going to explain how to do it with PuTTY and its associated programs, PuTTYgen and Pageant. If you installed the full PuTTY package, you’ll have all three programs already installed. If not, download the installer and run it now. (Be sure to get the full package, under the heading “A Windows installer for everything except PuTTYtel,” and not just putty.exe.)

Creating Your Keys with PuTTYgen

To create your public-private key pair, run PuTTYgen. There’s several types of keys, but SSH-2 RSA is the most common and is selected by default. (If this doesn’t work, you’ll need to check with your host to see what type of key their SSH server is expecting.) The number of bits defaults to 1024, which is fine. So all you have to do in the PuTTYgen window is click the Generate button, and then wiggle the mouse around a bit. The mouse movements generate random data that ensures that your key is unique.

When PuTTYgen is done creating the key, it will show a long string of characters that make up the public key. Select this text and paste it into a file, named something like id.pub (using notepad or any simple text editor). I made a folder at the root level of my C drive called SSH to store these keys and other related info, but you can put it anywhere you can find it later. (Note: you can also click the Save Public Key button and enter a file name, but this file won’t work as an alternative to the id.pub file we generated with cut-and-paste. It includes line break characters that confuse the server-side SSH code.)

Now you need to save your private key. If you just click the Save Private Key button, PuTTYgen will ask if you really want to save it without a passphrase, because we didn’t enter one. Here you have a choice to make between convenience and security.

The passphrase is essentially a password for accessing the key. Once you have your public key uploaded to your server (which we’ll do shortly), anyone who has access to your private key will have access to your server. If you use password protection on your PC, and you’re the only one with access to it, you might be comfortable going without a passphrase. But it is safest to use a passphrase, and we’ll soon see how you can make it so you only need to enter it once each time you boot your system. So to set a passphrase and save the private key:

  • Enter it twice, once in the Key Passphrase field and once in the Confirm Passphrase field. Keep in mind that this passphrase is essentially the key to accessing your server, so make it a robust password.
  • Click the Save Private Key button, and enter a file name (no extension) for your private key. The .ppk extension is automatically appended.

You now have your key pair and are done with PuTTYgen. Next you need to upload your public key to your server and set up your PC to access your private key.

Uploading Your Public Key

The details of uploading your public key may vary depending on the server configuration. The instructions below are for Rails Machine and are derived from the Mac and Linux oriented instructions they provide.

Open an SSH session to your server (using PuTTy, or another client if you prefer, as described in my previous post.) You probably have more than one user account; in my case, following the recommended practices from the Rails Machine folks, I have a root account that I never log into directly, and regular user accounts of Michael and Deploy. The Deploy account is the one I use for almost all communication with the server. So log into that account, or its equivalent for your setup. You’ll have to manually enter the password one last time.

Now, in the shell window that is connected to your server, create a directory for the private key file:

mkdir ~/.ssh

This creates a directory named .ssh within your home directory, which is where the SSH server will look for the public key.

Now set the permissions for this directory so you, but only you, have all privileges:

chmod 700 ~/.ssh

Now you have a directory on your server to hold your public key, and you need to move the key up there. There’s various tools you can use to do this. One tool you should become comfortable with is scp, or secure copy. It is not built in to Windows, but there is a version of it that comes with PuTTY, called pscp. If you add the path to the PuTTY program directory to your system path, you’ll be able to use pscp in any command window. (You may also want to install a set of Unix-style utilities; you can install the entire Cygwin environment, or if you want something lighter weight just for SSH-related tasks, get just the OpenSSH utilities. In either case, make sure to add to your Windows system path the folder in which these programs are stored, so you can use them from any command window without having to type their full path.)

To copy the public key, follow these steps:

  • Open a Windows shell in the folder in which you’ve stored your public key. (If you installed the Command Here utility as I recommended in the previous article, you can just right-click the folder and choose Open Command Window Here.)
  • In the command window, type

pscp id.pub username@hostname.com:~/.ssh/authorized_keys

(Of course, you’ll need to replace “username” with your actual user name, and “hostname.com” with the name of your server. If you’ve named your public key something other than id.pub, replace that name as well. Finally, if you’re using scp from OpenSSH instead of PuTTY’s pscp, drop the p in the command name.) This will copy your public key to a file called authorized_keys in the .ssh directory in your home directory.

Finally, to make the key file a little more secure, go back to your SSH window (remember, we started there but then switched to the Windows console), and type:

chmod 600 ~/.ssh/authorized_keys

This ensures that only the owner of this file (that’s the user name you began your SSH session with) can read or write it.

Making Your Private Key Available in Windows

OK, we’re almost there. Now we need to enable Windows programs making SSH connections to access your private key file. You could set PuTTY to use the key file, but that doesn’t buy you much, since it will ask for the passphrase every time you open a connection, and it won’t be available to other programs (such as Capistrano). So, you need to use another program called Pageant, which is installed along with PuTTY, to load the key into memory and make it available to other programs.

You can run Pageant directly via Start > All Programs > PuTTY > Pageant, and then you can tell Pageant to load your private key. But assuming you want the private key to always be available, you want it to load automatically upon startup. To do so, create a text file called load_private_key.bat (or whatever), with the following contents:

start “Pageant” “c:/Program Files/PuTTY/Pageant.exe” c:/ssh/id.ppk

Note that you’ll need to change the path to Pageant.exe if you didn’t install PuTTY in its default location. The id.ppk file is the private key file that you generated from PuTTYgen. (Using the “start” command, rather than simply providing the path to Pageant directly, prevents a DOS window from being left on the screen. Thanks to Tim Jervis for this tip.)

Finally, add this batch file to your startup tasks (Click Startup > All Programs > right click on Startup and choose Open, then right-click the load_private_key.bat file, drag it into the startup folder, and choose Create Shortcut from the menu that appears when you release the mouse).

Now, when you reboot your system, the batch file will run, Pageant will load your private key, and you’ll be prompted for the passphrase that you specified when you created the key. Enter this passphrase just this once, and your private key is now available to all SSH functions. When you shut your computer down, everything is secure again.

Setting up Subversion

If you’re using Subversion, you need to take one more step to enable it to use the private key generated by PuTTYgen: adding a line to Subversion’s configuration file.

Subversion’s configuration file is located in the Application Data directory under your user account. The full path is:

C:\Documents and Settings\{your windows user name}\Application Data\Subversion\config

Note that Application Data is a hidden folder, so to locate this file you must have Windows set to show hidden files and folders.

Open the config file in any plain text editor (such as Notepad) and add the following line:

ssh = $SVN_SSH plink.exe

plink.exe is the command-line link setup program that is included with PuTTY.

You’ll also need to make sure that the PuTTY directory is listed in your system’s Path.

Unfortunately, plink insists on popping up a DOS window, which is annoying. If anyone knows how to stop it from doing this, please let me know!

You’re Done!

That was simple, wasn’t it? :-) This may seem like a lot of trouble to go to just to avoid having to type your password, but once you’ve set this up once, you’re done. And if you’re using an automated deployment tool such as Capistrano, you’d have to type your password multiple times for a single deployment (since one deployment involved multiple SSH commands and other actions); with this setup, it can be fully automated.

Author: "--"
Send by mail Print  Save  Delicious 
Date: Thursday, 24 Jul 2008 08:00

This final RailsQuickStart lab write-up describes changes we’ve made to the sample application. Some changes are just code clean-up, while others implement some of the additional features suggested at the end of each lab.

To use the new code, check it out from our shared Subversion repository (see the Lab 7 writeup if you need a refresher on how to do this) and migrate to the current database version (rake db:migrate).

Page model

The most dramatic change is the addition of a Page model, and its associated pages_controller and views. This replaces the old static_controller, which we’ve purged. By using a model to store the content and metadata for each page in the database, an administrator can update page titles and set page description and keyword metadata without having to edit code.

Controller and view code

The page model is administered just like any other, with the usual create and edit views.

To render each page, we added an action called simply “view”. The method in pages_controller is:

  def view
    unless @page = Page.find_by_name(params[:name])
      render :action => 'error' and return
    else     
      login_required if @page.protect
      @current_tab = @page.navtab
    end
  end

We find the page by its name, and if there is no page of a matching name, we render the error page. Assuming it is found, we check its ‘protect’ attribute, and if that is set, we require login to view the page. Finally, we set the @current_tab value, which is used by application layout to highlight the appropriate tab.

The “view” template is very simple, since all it is doing is rendering the contents of the page body attribute:

   <%= render_to_string :inline => @page.body %>

Note that we are not just using <%= @page.body %> here, because we want the body to be intepreted as ERb. Because the render_to_string method is not normally available in views, we need to add this line to pages_controller to make it available as a view helper:

	helper_method :render_to_string

The joys and dangers of ERb

The body for each page, as read from the database, is interpreted as ERb, so you can use helpers and other code. This gives you complete control over what goes on each page; you can use the helpers we wrote for content blocks and images to include items from those database tables, and you can use the usual ERb code to display data from other models.

There is a danger to this, however, which you should be aware of: there is no restriction on what code can go in an ERb block, so it could, for example, delete everything from the database. It can even issue system commands and wipe the file system. With great power comes great responsibility. Presumably, the only people who would be allowed to log in and edit the pages would be people you could trust.

If you want to use a similar approach but in a safer way, take a look at the Liquid templating language. It is similar to ERb for displaying data but does not allow destructive operations or access to system commands.

Creating pages

In addition to the migration that creates the Page model, we added a migration that populates the three pages that used to be handled by the static controller. You can edit the content of these pages by going to the main admin page, clicking on Pages Admin, and then clicking the Edit link for the appropriate page.

If you add new pages, you’ll need to add them to the navigation bar, or put a link on another page somewhere, so users can access them. You could take this design a step further by creating the nav bar from the Page model, so that each new page would automatically get a nav button.

Note that pages that are created from other models, such as the resources page, are independent of the Page model, and for those pages, the page title and metadata are set via instance variables in the controller, just as we did in the static controller. We’ve made changes to the application layout so the description and keyword metadata can be set, in addition to the page title.

Putting metadata in the layout

We want to take the metadata (title, description, and keywords) for each page and put it in the page header, so we need to do that in the layout. These lines go in the head section of views/layouts/application.html.erb:

   <% if @page %>
      <title><%= @page.title %></title> 
      <meta name="keywords" content="<%= @page.keywords %>" />
      <meta name="description" content="<%= @page.description %>" />
   <% end %>

If there is a page object (remember that some pages, like the resources page, are not generated from page objects), then we render the HTML required for each piece of metadata, pulling the contents from the appropriate attribute of the @page object.

Supporting routes

We added a couple of routes to support the Page model:

   map.root :controller => "pages", :action => "view", :name => 'home'
   map.connect ':name', :controller => "pages", :action => 'view'

The first route makes the page named “home” function as the home page of the site.

The second route causes any URL that consists of a single word to invoke the view action in the pages controller, and pass that word as the :name parameter.

Resource page enhancements

We modified the view for the resources page so it doesn’t show a category heading if there are no links for that category. This is just a one-line change in links/resources_page.html.erb:

   <% if category.links.size > 0 %><h2><%= category.name %></h2><% end %>

We also added a route for the resources page so the simple URL “/resources” would work:

   map.resources_page '/resources', :controller => 'links', :action => 'resources_page'

Since we gave the route a name (after “map.”), we can refer to it in other places, such as in the nav link in the application layout, as resources_page_path.

User management

We added an admin page that lists all the users, and allows you to delete users and to change their passwords. Take a look at users_controller and views/users/index.html.erb to see how this works. Here’s the heart of the index view:

<table>
<% @users.each do |user| %>
   <tr>
      <td><%= user.login %></td>
      <td><%= user.email %></td>
      <td><%= link_to "Delete", user, :confirm => 'Are you sure?', :method => :delete %></td>
      <td><%= link_to "Change Password", :controller => 'users', :action => 'change_password', :id => user %></td>
   </tr>
<% end %>
</table>

On each row of the table, we show one user’s login and email, and provide links to delete that user or change their password.

Creating the first user

We had disabled the requirement for login to access the users controller so you could create your first user, but obviously this makes the entire system completely insecure. So we’ve re-enabled the login requirement.

This creates a quandary if you’re starting with an empty database: you can’t log in to create your first user if there are no users. You could use the Rails console to create a user, but to make this easier, we added a migration that creates a user “admin” with the password “seminar” (in the file db/migrate/013_create_admin_user.rb):

   def self.up
      User.create(:login => 'admin', 
                  :email => 'noone@anydomain.com', 
                  :password => 'seminar', 
                  :password_confirmation => 'seminar')
   end

You should either change the password (which you can now do via the Users Admin page) or delete this user if you’re using this code in a production environment.

Making things a little prettier

We’ve added some styling to the forms, so they’re a little more respectable. This includes changes in the html pages, as well as some additional CSS styles. We’ve also linked the standard Rails scaffold.css file in the application layout, which provides styling for validation error messages and highlights fields with errors.

There’s one thing we don’t like about the way the standard Rails error display works. Fields that have errors are wrapped in a div that has an ID of “fieldWithErrors”. This lets the stylesheet apply different styling to fields that have errors.

But a div is the wrong element to use for this; for one thing, it messes up the layout of the forms when there is an error. We added a little code to environment.rb that makes Rails use a span, instead of a div, to avoid this problem:

   ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "<span class=\"fieldWithErrors\">#{html_tag}</span>" }

This is a little obscure, but we didn’t have to figure it out ourselves; a little bit of Google searching with a description of the problem revealed this solution.

On the new subscription page, we combined all the error messages into one block by listing all of the models on one line:

   <%= error_messages_for :subscription, :customer, :creditcard %>

Finally, we added some styles to our quickstart.css style sheet that override some of the styles in the standard Rails scaffold.css. We also added a little default styling for the table element so the admin pages would look a little better.

Testing Purchases Through Mock ActiveMerchant Gateway

In the code we developed previously, we weren’t testing the creation of a subscription (where ActiveMerchant gets called). In this bonus lab, we refactored SubscriptionsController.create to lend itself to testing. We needed to make a few changes:

  1. change the create action itself to allow swapping in a test gateway object;
  2. change the environment setup files to use the proper gateway depending on whether you were in test, development, or production;
  3. and add some tests.

Fortunately, ActiveMerchant provides many tools to help with testing. The PeepCode Active Merchant PDF is an excellent resource that you should check out.

Refactored SubscriptionsController.create

We refactored the code to look like this:

def create
  # render :inline => "<%= debug params %>" and return
  @current_tab = "subscribe_tab"
  @page_title = "Please correct the errors below"
  @subscription = Subscription.new(params[:subscription])
  @subscription.amount = Subscription.cost_for_period(@subscription.period)
  @customer = Customer.new(params[:customer])
  # create the creditcard object and get name from customer object
  @creditcard = ActiveMerchant::Billing::CreditCard.new(params[:creditcard])    
  @creditcard.first_name = @customer.first_name
  @creditcard.last_name = @customer.last_name
  # make sure all three models are valid
  @customer.valid?
  @subscription.valid?    
  #
  # Our test code uses bogus credit cards for signaling various conditions to the 
  # bogus gateway. In test mode, the creditcard is never "valid", so work around that
  # here. The better thing to do if you are going to do creditcard stuff in the future
  # is to refactor this logic into separate classes. See PeepCode's ActiveMerchant PDF
  #
  unless (ENV['RAILS_ENV'] == 'test' or @creditcard.valid?) and @customer.errors.empty? and @subscription.errors.empty?
    render :action => :new and return
  end
  # if everything looks ok, send the purchase request to the gateway
  # set up options hash with billing address and ip
  options = {
    :ip => request.remote_ip,
    :billing_address => { 
      :name     => @customer.full_name,
      :address1 => @customer.address,
      :address2 => '',
      :city     => @customer.city,
      :state    => @customer.state,
      :country  => 'US',
      :zip      => @customer.zip,
      :phone    => @customer.phone
    }
  }  
  begin
    response = Subscription.gateway.purchase(@subscription.amount, @creditcard, options)
    # redisplay form if not successful
    unless response.success?
      flash[:notice] = "Transaction failed: #{response.message}"
      render :action => :new
    else
      # save the responses from the transaction in the subscription record
      @subscription.message = response.message
      @subscription.reference = response.authorization
      @subscription.test = response.test?
      @subscription.params = response.params.to_yaml
      @subscription.customer = @customer
      @subscription.save!
      flash[:notice] = "Thanks for subscribing to our site!"
      redirect_to root_path
    end
  rescue ActiveMerchant::ActiveMerchantError => e
    # Consider much better error handling (of ActiveMerchant specific exceptions)
    flash[:notice] = "Transaction failed: #{e}"
    render :action => :new
  end        
end

The unless clause that tests for valid objects changed. Our tests will use a bogus credit card object that ActiveMerchant’s test code knows how to use. The fake credit card encodes whether the mocked merchant gateway should succeed or not. This means we can’t use the validation check when we are in test mode.

We also rewrote the gateway usage itself. Now, we use a gateway that is stored in a class variable of Subscription. The gateway is created at initialization time, and this allows us to swap in different gateways if desired. ActiveMerchant supplies a mocked gateway and we use that when testing.

Note we also put the gateway usage between exception handling code (the begin/rescue/end blocks). If something goes wrong in the gateway during testing, or during real use, we catch that problem and send the user back to the data entry form.

Environment File Change and Subscription Model Tweak

Since we are creating the appropriate gateway at startup, we need to do that in our environment files. The code for test.rb looks like:

config.after_initialize do
  ActiveMerchant::Billing::Base.mode = :test
  Subscription.gateway =
    ActiveMerchant::Billing::BogusGateway.new
end

We are simply putting ActiveMerchant into test mode and setting the class variable in Subscription to hold an instance of the mock gateway object called ActiveMerchant::Billing::BogusGateway.

The Subscription class needed a small change to add the variable:

class Subscription < ActiveRecord::Base

  belongs_to :customer  
  validates_numericality_of :amount, :message => "Choose a subscription amount"
  validates_numericality_of :period, :message => "Choose a subscription amount"
  
  # The payment gateway we want to use is set in our environments, so we can
  # swap it out for testing
  cattr_accessor :gateway
  
  def self.cost_for_period period
    if period == 1
      995     # $9.95 in cents
    elsif period == 12
      9995    # $99.95 in cents
    else
      "invalid"
    end
  end
end

cattr_accessor is a method that creates a class level set of data accessors for a variable, in this case called gateway.

Some Tests

We tweaked the test_helper.rb file to add a helper that makes a creditcard hash object for us:

def credit_card(options = {})
  { :number => '1',
    :first_name => 'Bob',
    :last_name => 'Sample',
    :month => '8',
    :year => "#{ Time.now.year + 1 }",
    :verification_value => '123',
    :type => 'visa'
  }.update(options)
end

and we use it in several functional tests in our subscriptions_controller_test.rb file:

def test_should_create_subscription
  assert_difference('Subscription.count') do
    post :create, :subscription => { :amount => 1, :period => 1 }, 
                  :customer => {:first_name => 'bob', :last_name => 'Sample', :address => '123 main', :city => 'San Jose', :state => 'CA', :zip => '95000'},
                  :creditcard => credit_card({:number => '1'})
  end

  assert_redirected_to root_path
end

def test_should_not_create_subscription_failed_auth
  assert_no_difference('Subscription.count') do
    post :create, :subscription => { :amount => 1, :period => 1 }, 
                  :customer => {:first_name => 'bob', :last_name => 'Sample', :address => '123 main', :city => 'San Jose', :state => 'CA', :zip => '95000'},
                  :creditcard => credit_card({:number => '2'})
  end
  
  assert_response :success
end

def test_should_not_create_subscription_activemerchant_exception
  assert_no_difference('Subscription.count') do
    post :create, :subscription => { :amount => 1, :period => 1 }, 
                  :customer => {:first_name => 'bob', :last_name => 'Sample', :address => '123 main', :city => 'San Jose', :state => 'CA', :zip => '95000'},
                  :creditcard => credit_card({:number => '3'})
  end
  
  assert_response :success
end

The only difference between these three tests is setting the number of the creditcard to 1, 2, or 3. These magic numbers are used by the mock object to signal three cases: 1) good validation; 2) bad credit card validation; and 3) a fault in the gateway. See the ActiveMerchant documentation for more info.

But wait, there’s more!

There’s an assortment of other changes throughout the code: adding validations for most model fields, making the defensio code a little more robust, and fixing some tests.

What’s next?

That’s all, folks. If you find any issues with the code, or want to make any suggestions, please post to the Google group.

Author: "--"
Send by mail Print  Save  Delicious 
Next page
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader