Posted on 10-06-2008
Filed Under (Conferences) by Dary

More nuggets:

Advanced RESTful Rails by Ben Scofield (Viget Labs)
Pick out the nouns from your app to determine the resources
Decide what methods to expose to those resources
Ajax actions generally use middle man which is a join model

Fast, Sexy, and Svelte: Our Kind of Rails Testing Dan Manges (ThoughtWorks), Zak Tamsen (ThoughtWorks)

Unit Test

  • one method or object being tested at a time
  • Avoiding Unit Test Britleness:
  • gem “unit_record”
  • ActiveRecord::Base.disconnect! keeps tests from hitting db
  • To avoid db you could use fixtures (Difficult because you need to go back and forth to the fixture file)
  • Or you could construct the object

Functional Testing Speed

  • Gonna be slower – involve more objects and hit the db
  • DeepTest speeds up functional tests
  • Read DeepTest gem ReadMe to set up distributed tests – SUPER FAST!

Integration Tests

  • Sometimes useful for special purpose tests
    • performance tests
    • smoke tests
    • tests simulating multiple users

Acceptance tests

  • Better for low levels of granularity
  • Selenium RC – way to control the browser
  • Writing Acceptance Tests:
    • Encapsulate Pages
    • Data Access:
      • Can use Factory again to create entries
    • Parallelization – multiple Selenium RCs

Integration Testing with RSpec's Story Runner by David Chelimsky (Articulated Man, Inc)

  • Process
    1. Feature Injection
    2. Focus on outputs
    3. Acceptance Criteria – if tests pass, customer accepts it
  • Popping the “Why?” stack – ask “Why?” until value comes out

Integration Testing:

  • Make sure the component parts play nice together
  • Automated User Stories/Scenarios
    • Document the expected behavior of the system
    • Verify that behavior by executing a thin vertical slice of the system
    • Narrative Format: identify goal, user, action
    • Should test edge cases!
      • ex. goal of 200, 1 should return 1% and 199 should return 99%
    • Store DOM in memory
    • manipulates DOM
    • builds POST from DOM
  • Webrat Ruby gem (http://github.com/brynary/webrat)

Selenium RC (lets you test JavaScript/AJAX & you can watch it!)

  • Because it’s slow you should only use for AJAX and use Webrat otherwise
  • Multiple Sessions

The Great Test Framework Dance-off by Josh Susser (Pivotal Labs)

  • RSpec for the structural level
  • Shoula for test cases
  • Test/unit for assertions
  • Refactor with shoulda
(1) Comment    Read More   
Posted on 02-06-2008
Filed Under (Conferences) by Dary

Let's talk about the nuggets. Quick note though - I heard the complaint that the talks weren't technical enough. I don't particularly agree with that criticism. There's only so much you can cover in 45 minutes or whatever it is so I think the real purpose of most of these talks was to show us what's out there and it's up to us to dig further. My two cents. Anyways, the nuggets:

"Multi-core Hysteria": FUD about CRUD? by Andrea O.K. Wright (Chariot Solutions)-
Learned Mongrel mechanism for handling concurrent threads
def initialize(dir, meme_map = {}{
@guard = Mutex .new
}

Mutex Doc
Got this little forking snippet:
walking = fork do
100.times do
puts “walking”
sleep 1
end
end

chewing = fork do
100.times do
puts”chewing”
sleep 1
end
end

Surviving the Big Rewrite: MOVING YELLOWPAGES.COM to Rails by John Straw (YELLOWPAGES.COM) -
(This talk was awesome for me personally as it dealt with moving a large, established Web site to Rails)
Why the move? Absolute control of URLs (of utmost importance for their site), stateless HTTP, being agile & writing less code
His team and their development process which was pretty cool: ~20 people (5 core developers), sat together, 3 week (approx.) cycles - 1 week wireframe development, 1 week UI design, 1 week+ development
Web Service performance issues they tackled:

  • Slow page performance caused more by asset download times than speed of web framework
  • Worked through the Yahoo! performance guidelines
  • Minified and combined CSS and JavaScript with asset_packager
  • Moved image serving to Akamai edge cache
  • Apache slow serving analytics tags – moved to nginx for web tier

Also, they debated about other technologies (Java/EJB3, Django) but eventually chose Rails because, well, it's the bomb.

CRUD Doesn't Have an 'S' in It: Managing Complex Searching in Rails by Stephen Midgley (Hutz.com)
4 architectural steps (in order):

  1. POST/GET Params representing Search Criteria
    • e.g. ?s=search_parameters
  2. Merging Search Criteria with persistent criteria
    • Session/backend, hidden input tags or on the URL line
  3. Converting Search criteria to Search Rules to SQL
  4. Paginating the Search & Render

I loved this: For clean URLs use POSTs. Make sure your URLs are distinct for core search options. If your URLs aren’t clean, you’re doing it wrong!!!

  1. Clean: http://mysite.com/find-vacations/p/1/United-States/Califronia
  2. Not Clean: http://mysite.com/controller/action?wtf=is&all=this

You want to store your SQL in an object so that you can pass it around

  1. This makes writing your Search Rules more modular
  2. Doesn’t have to be session (maybe you want searches sshared across users?)
  3. Caboose::EZ

SQL Tools

  1. EZ-Where
  2. Squirrel
  3. Sequel

Alright so that's what I got for Friday. Saturday and Sunday coming soon...

(1) Comment    Read More   
Posted on 01-06-2008
Filed Under (Conferences) by Dary

**Please see my follow-ups on individual days: Friday, Saturday, Sunday**

RailsConf 2008, two words: passionate and fascinating.

I met so many people over the past 3 days who are absolutely in love with the work they're doing. I met pod/screencasters Gregg Pollack (Rails Envy Podcast), Ryan Bates (Railscasts), Chistopher Haupt and Michael Slater (Learning Rails), and Geoffrey Grosenbach (Peepcode & Ruby on Rails Podcast). Everyone's familiar with their work I'm sure, but needless to say their depth of knowledge and eagerness to help out and get others involved was amazing. I've got a whole list of tips & tools for podcasting and screencasting now and several friendly contacts to help me along the way. I met Evan Phoenix, Brian Ford, and Wilson Bilkovich from Engine Yard who are the lead developers of Rubinius. Their presentation was great and I feel like I have a much better understanding of why Rubinius is important and useful. And I'm actually itching now to get commit rights (it doesn't take much!) I also met David Chelimsky, fellow sports fanatic and RSpec guru. We had a really interesting 5 minute chat about the new story runner feature in 1.1 and I'm really excited to explore ways to integrate it into my development process. And that's just the tip of the iceberg! There are about 20 other people I had conversations with, learning about their projects, what tools they use, what they like (love) about developing with Rails, what they don't, etc etc.

And all of the talks were so interesting! There was a nugget or two (or six) of programming goodness in literally every talk I attended. I'll expand on the talks I attended in more depth coming up, but needless to say there wasn't a single striking disappointment among the bunch. They were all fascinating, which of course is a direct by-product of having so many people doing something they're so invested in and that's so much fun to do.

In Conclusion,

Can't wait for RailsConf 2009!

(7) Comments    Read More   
Posted on 15-05-2008
Filed Under (Code, Process) by Dary

I tried to use Ruby's built-in Active Record fixtures module to import an Excel-exported CSV file. No dice. Kept getting cryptic errors about improper formatting. Whoops. So then I installed this wicked cool gem named FasterCSV and piggy-backed off of this migration import script and everything went great. So for all those people with ancient (and kinda useless) Excel data files, now there's a relatively quick and painless way to import them into SQL dbs. Here are the steps I went through:

Install the gem:
sudo gem install fastercsv

Now I have several tables in my College Football spreadsheet and for this example I'll use the one with ratings data for College Football games. Each entry has a game_id, region_id (for the various regions where ratings data comes from, e.g., Atlanta and Austin), a rating, and a duration in quarter hours (since some games are only cut-ins, e.g., Georgia Tech-Georgia ends early and the Atlanta region picks up the last half hour of the Texas-Oklahoma game). So here's the script that imports my gross Excel spreadsheet into a useable SQL table - db-agnostic by the way (How do I love thee Rails? Let me count the ways.)

require 'fastercsv'

class LoadRatingsData < ActiveRecord::Migration
def self.up
FasterCSV.foreach("#{RAILS_ROOT}/db/migrate/fixtures/ratings.csv", :row_sep => "\r") do |row|
id,game_id, region_id, rating, duration = row
Rating.create(:id => id, :game_id => game_id, :region_id => region_id, :rating => rating, :duration => duration)
end
end

def self.down
end
end

And it's just that easy. Another cool thing, that I haven't done yet, is that you could take that one bulky Excel sheet that has way too much information in it, break it into useful models, and form actual relationships between the data. What a novel idea!

In Conclusion,

This rules!

(7) Comments    Read More   

I wrote a script tonight to curl several URLs, but sleep for 2 minutes in between each request. I piggybacked on a little script written by programmer John McCann from NYC. Here's what the code looks like:

#!/usr/bin/env ruby
RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/..')

require File.join(RAILS_ROOT, "config/environment")

puts "writing curl script..."

t1 = Time.now

foos = Foo.find_by_sql("select distinct bar from foos;")

curls = foos.map! {|foo| "curl 'https://some.api.com?data=%7Bfoobar%3A#{foo.bar}%7D&key=12345'\n"}

curl_script = curls.join("sleep 120\n")

File.open("curl.sh", "w") {|f| f <<>

t2 = Time.now

puts "curl script written in " + (t2 - t1).to_s + " seconds"

What's fun about this script is that it was a new challenge for me on a couple fronts. I learned about encoding curl requests (%7Bfoobar%3A#{foo.bar}%7D produces {foobar:[value_of_foo.bar]}). After clumsily grabbing all objects and filtering after the query, I refactored the SQL to just grab distinct values from the db. I learned that the "w" attribute of the File.open class method either creates a file or sets its byte count to 0 if it already exists. And finally I learned about the "sleep" function which takes an integer parameter representing the number of seconds to wait until the next line is executed - this was especially helpful in not hammering the service I was accessing.

So not a major script, but pretty fun and interesting nonetheless.

In Conclusion,

I heart curl.

(0) Comments    Read More   
Posted on 05-05-2008
Filed Under (Code) by Dary

View Here

Behavior-driven development (BDD) is a programming paradigm that emphasizes defining behavioral characteristics of your code before actually writing any code. An example is if I'm defining a calculator controller my calculator should return 2 when given the equation 1 + 1, should return an error when trying to do division by 0, etc. By clearly defining what your code should do before writing it, it makes it much easier to write solid, test-covered code upfront and makes it a cinch to debug as you go along because you're immediately alerted whenever new functionality accidentally breaks legacy portions of your codebase.

I've found BDD much more intuitive than TDD (test-driven development). The above video by Dave Astels, one of the original developers of rSpec, gives a nice overview of BDD vs. TDD and the pros of the former. Also touches on the benefits of using a dynamic language like Ruby.

In Conclusion,

Pretty neat...

(0) Comments    Read More   
Posted on 05-05-2008
Filed Under (Random) by Cody

We are currently looking for a Sr. Web developer who:

  • has Ruby on Rails experience
  • is a big sports fan
  • wants to work with AWS 
  • wants to prove Rails can scale

Here's the official stuff:

If you are interested please apply online at http://www.espn.com/joinourteam.

If you know anyone that might be interested please feel free to pass this information on.

Title - Sr Web Developer
Location: Los Angeles

Job Responsibilities
The ESPN Digital Media Community Product Development team is responsible for developing the digital products that support ESPN’s Community Strategy.

The Sr Web Developer is responsible for the design, development, testing, implementation, scalability and
deployment of Ruby on Rails-based applications to support the Community Product Development initiatives.

These applications provide functionality for many of the most successful and highest profile
sports-related features on the web.

Responsibilities

  • Design, develop, test, implement, scale and deploy new Ruby on Rails based applications.
  • Develop new features and functionality for existing applications.
  • Support the existing Community infrastructure and applications.
  • Provide support to entire team by developing functionality needed to create new web applications and features.
  • Identify areas that require improvement and recommend/implement solutions.

Required Qualifications:

  • Degree in Computer Science or related field, and/or equivalent work experience.
  • At least 3 years of related experience with 2+ years experience with Ruby on Rails and web applications
  • Demonstrated experience developing in a RoR environment
  • Proficiency in a MySQL, SQL Server or Oracle database technology
  • Experience working in a virtualized environment such as Amazon's EC2 would be a plus
  • Understanding of multi-tier web architectures, and OO design patterns and concepts.
(0) Comments    Read More   
Posted on 01-05-2008
Filed Under (Tutorial) by Cody

I am about as excited as a wolverine caught in a beaver trap about writing this post.

But, I have to test some stuff out for Fan Profiles, so here we go. I'm going through the steps as I write, so, I guess this is live blogging and anything can happen on a live blog.

Installing Ruby and Ruby Utilities

  1. Get Ruby Installer
  2. Verify that everything was installed:
     
    C:\&gt; ruby -v
    C:\&gt; gem -v

    Ruby should be 1.8.6 and gem should be 1.0.1 or greater

Installing MySQL

  1. Download and install MySQL 5. It's an older version because the newer installers have bugs with Vista....still
  2. *Some Vista hackery from Building Web Apps:
  3. *First, go to the Start Menu, select Control Panel, and then click on User Accounts and Family Safety
  4. *Click on the User Accounts link to open your account’s setting dialog:
  5. *Click on the Turn User Account Control on or off link: Uncheck the box. DO NOT RESTART YET.
  6. *Open Control Panel again, and select the Allow a program through Windows Firewall option of the Security group.
  7. *Press the Add port... button, and enter MySQL in the “Name:” field and 3306 in the “Port number:” field. Leave the protocol as “TCP”.
  8. Double-click the community edition (open source) Windows Essentials MySQL to run the MySQL installer. The typical option is fine.
  9. Make sure the check box is checked to configure MySQL and click "Finish"
  10. OK, that did nothing for me. The wizard just exited.
  11. Oh, NOW restart your computer. (Be back in a few)
  12. OK now run the installer and REMOVE MySQL
  13. Now run it again, and install the stupid thing
  14. You should now be able to configure it
  15. Select Detailed Configuration
  16. Select "Developer Machine"
  17. Select "Multifunctional Database"
  18. Select "Decision Support"
  19. Leave "Enable TCP/IP Networking" and "Enable Strict Mode" checked
  20. Check "Best Support for Multilingualism"
  21. Check "Install as Windows Service" and "Include Bin Directory in Windows PATH"
  22. Give root a password: I used "root". I mean it's a developer's box. Don't be a security freak. It's unbecoming.

Rails and other gems

  1. gem install rails --include-dependencies -y --no-rdoc --no-ri
  2. gem install capistrano --include-dependencies -y --no-rdoc --no-ri
  3. gem install mongrel --include-dependencies -y --no-rdoc --no-ri
  4. gem install mongrel_cluster --include-dependencies -y --no-rdoc --no-ri
  5. gem install mysql --include-dependencies -y --no-rdoc --no-ri

RMagick (GASP!!!!!)

  1. Download the zipped binary gem: Download
  2. Unzip it
  3. Run the ImagicMagick Installer, and keep all the default options
  4. cd into the unzipped directory from the command prompt
  5. gem install rmagick --local --include-dependencies -y --no-rdoc --no-ri
  6. Restart your computer

Our IDE: Aptana

  1. Download and install Aptana Studio: Download
  2. Radrails: Click "Install" from the Aptana Start page that opens up by default and just keep checking and clicking next.
  3. Subclipse: Help > Software Updates > Find and Install > Search for new features to install > Select Subclipse and then keep checking and hitting next till it's installed.

Well, that wasn't as painful as I thought it would be, but I still feel like I have to go take a shower.

Or go code up something on my MacBook Pro. Nothing beats Rails development on a MacBook Pro.

UPDATE: Apparently this will work for Windows XP. The "*" parts are Vista only.

(0) Comments    Read More   
Posted on 30-04-2008
Filed Under (Code) by Cody

When we launched Fan Profile just over a week ago, we knew there would be bugs, refactoring and tuning.

There always is.

Minus the bugs, I love this phase. The pressure to launch is gone, and my attention turns to making the product perfect. I mean, who doesn't like perfection?

This time, my pursuit took me and the entire team into huge pile of CRUD.

I had just finished reading the "Gospel of the Seven Actions" (new, show, index, edit, update, create, destroy), and just that easily, I became a born again CRUDian.

My plan was to go through all our controllers and simultaneously tune queries, move code to models and "CRUDify" manufactured actions such as "search, about, mail, send_group_invite" and more.

I figured I could do it incrementally and quickly, so there was no need for a branch -- I'd be done in a day, day and a half.

Whoooopsss.

Yeah, I'll branch in the future because this was no easy task.

Some actions just don't fit nicely into one of the seven. For example, what about an action that takes a comma separated list of positions and rearranges a user's favorite teams based on those parameters?

Well, I had called it "reorder," but delving into the Gospel, I found out that what I am in fact doing is updating an existing order, so we get:

 
map.resources :users as 'fans' do |users|
  users.resource :team_orders, :controller => :user_team_orders
end
 

Notice it is resource not resources. This means that a team can have ONE order, so you can specify the update action without specifying an id, which is good because there is no "order" model anywhere that maps to a table.

In the case of groups, we actually split one controller into eight, but the task is winding down.

I'm fixing the tests and caching and then I'll QA, hopefully in time for a release Monday. Then Fan Profiles will be one giant piece of CRUD where all exposed actions will be "one of the seven" (cue the choir).

If I didn't have a financial accounting mid term on Sunday, I'd celebrate our walk into the CRUDdy light.

(0) Comments    Read More   

I recently sat in on part of ABC's two-day Digital Media Developer Summit.

Lex Sisney, CEO of ELC, which we teamed up with with for development and training, spoke about Agile and Iterative development, open source and how they could fit into ABC's developer stack.

Lex touched on three trends:

1) Success of agile/iterative project management
2) Emergence of developer friendly programming languages (specifically Ruby)
3) Commoditization of hosting (Amazon Web Services)

I spoke about how the ESPN Community Group utilizes these three trends for our development process. Oh, ESPN and ABC are part of Disney, which is why I got the invite in the first place.

We got a great reception from the various developers and managers there, which was great. These folks use the same proprietary technology and project management methods we used to use and I got the impression there is a lot of excitement for trying new technologies, methods and hosting solutions.

One of the best questions was what are the fringe benefits we've enjoyed from using all open source methods and technologies. As a manager and developer, I have noticed several:

1) Greater number of applicants for positions
2) Developers acquire skills more quickly
3) Developers acquire a much broader range of skills
4) Developers are more eager to improve their knowledge and skills (because they are acquiring marketable assets)
5) We have become part of a much larger community. Both in terms of taking and giving, we are active in the community through code sharing, Google Groups and much more.

Another great question regarded the combination of Test Driven Development, Agile Development and Ruby on Rails and if they can be separated.

I think Lex answered this best by saying TDD and Agile are methods and RoR is a great tool to use with these methods.

But it is interesting because Agile and TDD almost go hand-in-hand with Rails because the stack is so conducive to those methods that developers would almost have to fight against the methods NOT to use them with Rails.

Any language or stack (especially MVC stacks) can utilize TDD and Agile as processes, but both were baked in with Rails.

I can't think of any reason why that's bad, but I'd be interested to hear arguments on negatives to that.

The last big theme that I tried to stress is that we are not forcing or trying to force any one to adopt our methods or technologies, but merely present that, even in a large company with established methods and technologies, change still can happen, and languages, methods and hosting can be chosen to fit a particular application or product.

For example, I said that moving from Java to Ruby to do the heavy SAX-based parsing of statistical data feeds probably wouldn't be the best idea, but Ruby may be a much better solution for building a new social network.

So I am very glad Lex and got to share knowledge with developers from another part of the community. I hope the company as a whole embraces different solutions, so we can move beyond boundaries created by a particular technology and join a very smart and open community.

(0) Comments    Read More