• 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

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

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

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

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

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

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

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 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 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

When I’m writing content for the web, I hate dealing with HTML coding. HTML is rather verbose as a markup language, and having to include closing tags is messy and error-prone.

We’re all pretty much stuck with delivering HTML code from our web sites, but that doesn’t mean we have to write in it. There are various markup approaches that are superior to HTML when it comes to content creation, and which can be used as source code from which to create HTML. Two that are widely used are Textile and Markdown.

Textile was originally developed by Dean Allen for the TextPattern content management system and is now widely used in wikis and blogs. Markdown, created by John Gruber and Aaron Swartz, is an alternative that is conceptually similar but with a different syntax. Many of the popular blog engines provide a choice of Textile or Markdown (or HTML) for posts and comments (this site offers Textile).

In this article, I’ll show the basics of Textile markup and how easy it is to use it in Rails applications.

What is Textile?

Textile strives to make text markup as clean and simple as possible. You don’t have to put <p> in front of each paragraph; bare text is automatically surrounded by <p> and </p> tags. To make a first-level heading, just start the line with @h1. @. For example:

h1. This is a heading and will be wrapped in <h1> and </h1> tags

This is a text paragraph and will be wrapped in <p> and </p> tags.

This is another paragraph.

And I bet you can guess how to make a second-level heading, or a third-level heading.

You never need to use close tags; a pair of carriage returns automatically triggers the appropriate end tag. Quotes are automatically converted to open and close quotes; hyphens are converted to n-dashes (if there is a space on either side); and double hyphens are converted to m-dashes.

To make text bold, surround it with asterisks; to make it italic, with underscores:

*This text will render in bold*
_This text will render in italic*
_*This text will render in bold italic*_

To add a link to a piece of text, surround the text in quotes, and follow it by a colon and the URL:

"text to be linked":http://thisistheurl.com

To include an image, type its URL surrounded by exclamation points:

!http://domain.com/path/to/image.jpg!

To create a bullet list, start each line with an asterisk and a space, like this:

* First item
* Second item
* Third item

Want a nested bullet list? Just indent the asterisk by three spaces.

There’s more, but this should give you a feel for it. You can also use any HTML you want for things that Textile doesn’t cover — HTML code is simply passed through. For more details, see the Textile Reference. You can try out Textile online at the Textile home page.

Implementing Textile

There are Textile implementations for various environments. In my case, using Ruby on Rails, Textile is implemented by whytheluckystiff ’s RedCloth gem. (The current implementation does have some flaws, and a much-enhanced version called Super RedCloth is in development.) To install, just enter the following in the console:

gem install RedCloth

With RedCloth installed, you create a new RedCloth object and pass some Textile-marked-up text to it:

textile_styled_text ="h1. This is an example of a heading in Textile"
textile_object = RedCloth.new(textile_styled_text)

Then, when you want to render this as HTML, you simply use:

html = textile_object.to_html

Making Textile Even Easier

That’s pretty easy, but you can make it even easier. There’s a Rails helper “textilize,” but thanks to the acts_as_textiled plug from Chris Wanstrath, it’s even easier than that. Install this plugin:

ruby script/plugin install
 svn://errtheblog.com/svn/plugins/acts_as_textiled

And then all you have to do is declare a model attribute as Textile-formatted in your model class:

acts_as_textiled  :field_name

That’s it — everything just works! (Remember, though, that you need to restart the server for the model change to take effect.) Textile marked up text is stored in the database. Form fields automatically show unrendered textile. But any other use of the model attribute automatically delivers the rendered HTML instead of the Textile source.

Markup without Coding

You can also simplify the entry of Textile markup by using the textile_editor_helper from Dave Olsen and Chris Scharf. This plug-in renders a set of icons for the common markup tasks in your form view, just above the text entry area:

When you click an icon, JavaScript code inserts the appropriate markup into your text.

To use this, first install the plugin:

ruby script/plugin install
 http://svn.webtest.wvu.edu/repos/rails/plugins/textile_editor_helper

rake textile_editor_helper:install

And then replace the text_area tag in the form in which the user enters the Textile-formatted text with textile_editor:

<%= textile_editor 'object', 'field' -%>

textile_editor takes all the same options as text_area.

and at the end of the form add:

<%= textile_editor_initialize -%>

Finally, if you don’t already include prototype.js, you’ll need to add that to your layout:

<%= javascript_include_tag 'prototype.js' %>

Presto! Now you have a row of icons above the text area so your users don’t have to remember any markup at all. They’ll still see the markup in the text area (this is not a wysiwyg editor), which will help them learn the markup code.

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

All the cool kids in the web world these days seem to be using Macs, which have hearts of Unix so are natural complements to Linux-based servers. Others are running Linux desktops. So a lot of the remote server administration information on the web assumes that you’re on either a Mac or a Linux box.

For historical reasons, however, I have a collection of Windows systems, and they’re what I’m comfortable with. I also have some things, like my collection of 60,000 photos managed in the Photoshop Elements Organizer, that aren’t easily moved to a Mac, and I have lots of Windows applications that I own and am familiar with. So while I don’t have any religious feelings about it (please, spare me the Mac evangelism), I’m using Windows systems to remotely administer my web servers.

This really isn’t a problem, as there are ample tools available to make Windows do most everything a Linux system does, or a least everything you need to do to administer one remotely. But it does take a little more effort, at times, to track down the right tools and figure out how to apply them. If you’re early in this process, this article may help. (If, on the other hand, you’re a grey-beard Linux hacker or a Mac die-hard, you can stop reading now.)

Although there are GUI interfaces for Linux, remote administration is done predominantly from the command line. And if you want to follow the well-greased paths for deploying Rails applications, you’re going to be living in a command-line world. This is, of course, rather alien in the Windows environment.

There’s really two command-line environments you need to use: the Windows command shell, for taking actions on your local machine, and a Linux shell, for interacting directly with your server. The Windows shell is essentially a grown-up version of the old DOS prompt. Linux shells come in a variety of versions, with BASH being the most common.

Enhancing the Windows Command Window

You need to use the Windows shell to control your local development environment, and with some extensions (to be described in a later post), you can use it for some tasks that involve your remote server as well.

To open a Windows command shell, you can select Run from Start menu and then enter cmd and click OK. But there’s a better way: Microsoft offers a free add-on that lets you open a command window by right-clicking on any folder and choosing a new option that the add-on installs, “Open Command Window Here.” Aside from being quicker than the Start > Run > cmd approach, it opens the command window with the current directory set to the folder upon which you right clicked. Download the command window PowerToy. It is entirely painless and will make your life just a little bit simpler.

Now you should customize your command window settings, as the defaults are pathetic. The window has no menu, so it may not be immediately clear how one customizes it. The secret is to open any command window, right-click on the title bar, and choose Properties. Once in the properties dialog, here’s some things you might want to change:

  • In the Options tab, check the boxes to enable Quick Edit Mode and Insert Mode. This enables you to cut and paste text (you can’t use ctrl-X and ctrl-V like you can in a GUI environment). To copy, select the text and then click the right mouse button. To paste, just click the right mouse button.
  • Also in the Options tab, change the Buffer Size to 999, and the Number of Buffers to 5. This gives you more memory for past commands. At any command prompt, press the up arrow repeatedly to move back through previous commands. This can save a lot of typing.
  • In the Layout tab, increase the Screen Buffer Height to 2500, so you’ll have more text you can scroll back through after it scrolls off the top of the window. Increase the Screen Height to provide a window as tall as you’d like; I prefer 75 for my 1200-pixel-high monitors.
  • In the Colors tab, change the text and background colors if you’d like. White text on a black background is traditional and has a retro appeal, but I prefer black text on a white background.

When you’re done making changes, click OK, and then choose Save Properties for Future Windows in the dialog that appears. Now you’ll have a much nicer command window to work with from now on.

Get Set up for SSH

Although you can use the Windows command prompt to act upon your remote server, the primary method used to access Linux systems remotely is SSH (Secure Shell). There’s not an SSH client built in to Windows, but good free clients are available. The most popular is PuTTY. Download the PuTTY installer package. Choose the download labeled “A Windows installer for everything except PuTTYtel”, which will get you the complete set of PuTTY utilities, some of which you’ll want later.

Run PuTTY, and you’ll see a deceptively simple window. There’s actually lots of options here, which you can explore by clicking the categories on the left. But you can get started by using all the defaults and simply entering the name of your host (or its IP address) in the Host Name field and clicking Open. (To save yourself a little typing in the future, you can enter a name under Saved Sessions and click Save, and then the next time you can just double-click this name in the Saved Sessions list.)

Assuming PuTTY is able to connect to your host, you’ll then see another of those lovely white text on a black background windows (you can change these settings in the initial PuTTY dialog), with a Login: prompt. At this prompt, enter the user name your host assigned you, and then you’ll get a password prompt. Enter the correct password, and you’ll be online talking to your server, with essentially all the control that a user sitting at the machine has. All data sent back and forth is securely encrypted, so no one will be able to sniff your network traffic and figure out how to get into your server (unlike FTP, in which not only your files but also your user name and password are sent in clear text).

If you aren’t able to connect to your server (even to the point of getting a Login prompt), then check the following:

  • Make sure your host has enabled SSH access. If you have a shared hosting account, it might not be offered, or you might have to ask for it.
  • Make sure you have the host name right. This should be simply the domain of your web site. If it is a new account and you haven’t set the DNS yet, you can use the IP address.
  • If all else fails, check with your host to see if they’ve moved SSH to a port other than the standard 22. Some companies are doing this to reduce brute-force attacks. You can enter any port number in the PuTTY dialog.

If, on the other hand, you get the login prompt but it doesn’t accept your user name or password, double-check that you have these exactly correct. For some hosts, you may need to use “name@domain.com” and not just “name” for your login name. Check the signup material you received when you opened the hosting account.

Once you have these two command-line environments in place, you have the essential tools to both control your local development environment and to administer your server. Now you just need to know what to type into these windows :-).

For more information:

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 
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 
Next page
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader