Rack for Easy HTTP redirect

We recently moved our class sign-up to EventBrite.  It used to be hosted on heroku with the subdomain classes.blazingcloud.net.  However, when we changed our DNS to direct to eventbrite, it didn’t end up targetting our eventbrite subdomain: blazingcloud.eventbrite.com — hitting the EventBrite homepage instead.  Rack to the rescue!

We set up another Heroku app with just a one-line rack application.  All it needed was a rackup config file, called “config.ru” with the following line:

run Proc.new { [ 302, {'Location'=> 'http://blazingcloud.eventbrite.com' }, [] ] }

and voila! It does a simple re-direct to the new site.

remarkable validations for rails 3

I’ve been working on upgrading an app from Rails 2.3.11 to Rails 3.1.  It was using the old rspec-on-rails-matchers plugin to get validators like:

it 'verifies that login is between 3 and 40 characters' do
   User.new.should validate_length_of(:login, :within => 3..40)
end

I like that validation syntax, but lately when I see a plugins, I worry that I’m in for some archaeology. I did find a replacement gem, but it didn’t work on first try, so I read up on my options. I briefly considered shoulda, which is now compatible with rspec, but I settled on remarkable because it seems to match the syntax already in use. I wrote a little test rails app with a couple of models and was pleased the results.

Setup

rails new remarkable_app -T"
cd remarkable_app

add to Gemfile:

    group :development, :test do
      gem "rspec", "2.6.0"
      gem "rspec-rails", "2.6.1"
      gem "remarkable_activerecord", "4.0.0.alpha4"
    end

Then back on the command line, set up rspec:

rails g rspec:install

edit spec/spec_helper.rb to include (after require ‘rspec/rails’):

    require 'remarkable/active_record'

Create a Model

Then make a model to play with (on the command line):

rails g model person name:string email:string
rake db:migrate
rake spec
/Users/sarah/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec rspec ./spec/models/person_spec.rb
*
Pending:
  Person add some examples to (or delete) /Users/sarah/src/mv/experiment/remarkable_app/spec/models/person_spec.rb
    # Not Yet Implemented
    # ./spec/models/person_spec.rb:4
Finished in 0.00026 seconds
1 example, 0 failures, 1 pending

yay! ready to get started test driving some remarkable validations…

Test Driven Validation

Let’s test drive our first validation..

describe Person do
  should_validate_length_of :name, :within => 3..40
end

note that remarkable also supports:
it { should validate_length_of :name, :within => 3..40 }
For my new code I’ll probably write the more concise version, but it is nice that my old code should work.

$ rake spec
/Users/sarah/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec rspec ./spec/models/person_spec.rb
F
Failures:
  1) Person
     Failure/Error: send(should_or_should_not, send(method, *args, &block))
       Expected Person to be invalid when name length is less than 3 characters
     # ./spec/models/person_spec.rb:4:in `block in <top (required)>'
     # ./spec/models/person_spec.rb:3:in `<top (required)>'
Finished in 0.30367 seconds
1 example, 1 failure
Failed examples:
rspec /Users/sarah/.rvm/gems/ruby-1.9.2-p290@remarkable_rails3/gems/remarkable-4.0.0.alpha4/lib/remarkable/core/macros.rb:26 # Person
rake aborted!
ruby -S bundle exec rspec ./spec/models/person_spec.rb failed

add validation to my model…

class Person < ActiveRecord::Base
  validates_length_of :name, :within => 3..40
end

Test passes!

$ rake spec
/Users/sarah/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec rspec ./spec/models/person_spec.rb
.
Finished in 0.27601 seconds
1 example, 0 failures

More validations:

describe Person do
  should_validate_length_of :name, :within => 3..40
  should_allow_values_for :email, "[email protected]"
  should_not_allow_values_for :email, "sarah", "@foo", "whatever.com"
end

Reasonably nice error output:

$ rake spec
/Users/sarah/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec rspec ./spec/models/person_spec.rb
..F
Failures:
  1) Person
     Failure/Error: send(should_or_should_not, send(method, *args, &block))
       Did not expect Person to be valid when email is set to "sarah"
     # ./spec/models/person_spec.rb:6:in `block in <top (required)>'
     # ./spec/models/person_spec.rb:3:in `<top (required)>'
Finished in 0.29054 seconds
3 examples, 1 failure
Failed examples:
rspec /Users/sarah/.rvm/gems/ruby-1.9.2-p290@remarkable_rails3/gems/remarkable-4.0.0.alpha4/lib/remarkable/core/macros.rb:26 # Person
rake aborted!
ruby -S bundle exec rspec ./spec/models/person_spec.rb failed

Cheated a little on implementation by copying email validation from ActiveRecord docs… all good.

Now let’s add an association!

In app/model/person.rb:

describe Person do
  should_validate_length_of :name, :within => 3..40
  should_allow_values_for :email, "[email protected]"
  should_not_allow_values_for :email, "sarah", "@foo", "whatever.com"
  should_have_many :addresses
end

Watch it fail:

$ rake spec
/Users/sarah/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec rspec ./spec/models/person_spec.rb
...F
Failures:
  1) Person
     Failure/Error: send(should_or_should_not, send(method, *args, &block))
       Expected Person records have many addresses, but the association does not exist
     # ./spec/models/person_spec.rb:7:in `block in <top (required)>'
     # ./spec/models/person_spec.rb:3:in `<top (required)>'
Finished in 0.32615 seconds
4 examples, 1 failure

Make it pass:

$ rails g model address street:string person:belongs_to
      invoke  active_record
      create    db/migrate/20110721161741_create_addresses.rb
      create    app/models/address.rb
      invoke    rspec
      create      spec/models/address_spec.rb
$ rake db:migrate
.
Pending:
  Address add some examples to (or delete) /Users/sarah/src/mv/experiment/remarkable_app/spec/models/address_spec.rb
    # Not Yet Implemented
    # ./spec/models/address_spec.rb:4
Finished in 0.2998 seconds
5 examples, 0 failures, 1 pending

the rest is left as an exercise for the reader :)

Summary

Overall, I like the remarkable syntax. It seems reliable and on its way to a good release for Rails 3.

Test Driven Development at Blazing Cloud

Blazing Cloud will be offering a class on Efficient Rails Test Driven Development this October, taught by Wolfram Arnold. Wolf is an experienced Rails engineer who applies test-driven development in his consulting practice, and is returning to teach this highly successful class for the fourth time at Blazing Cloud.

For information or to sign up, please visit our class page at

http://classes.blazingcloud.net

For an idea of what to expect from this class, check out this video episode from the first session of a previous class, complete with course outline and objectives:

1st Episode

For a complete list of episodes, visit Wolf’s blog!

Client Side Validations

TL;DR

Luke Wroblewski did some sweet research on inline validations and found out that people think they are totally awesome. Brian Cardarella implemented that research in the gem client_side_validations. The gem automatically generates lots of client validations based on your rails model validations. I wrote an application showing some of its capabilities and how to extend its functionality. Alright guy, show me some source for how to use this gem. I don’t need the stinking source, just let me see your app.

The Long Version

Back in 2009, Luke Wroblewski performed some research on inline form validation and how users respond to different types of inline validations (i.e. javascript validations that give immediate feedback). People complete forms quicker, make fewer mistakes, and are more satisfied when filling out forms with inline validations.  When asked to fill out a registration form, people were 42% quicker at completing the form when inline validations were present. Awesome!

This is great information to have about the way people interact with forms on our websites. Imagine we are building our own registration form for our next sweet application and we add inline validation. Our users are going to be happier with the experience of registering, they will make fewer mistakes, and they will be able to start ACTUALLY using our totally-awesome application quicker. There is just one problem… Manually coding inline validations can be a somewhat cumbersome process. First, we have to make sure that our server-side validations are working properly. After we have tested the backend, we then need to manually code up a fair bit of javascript in order to get the inline validations working. Not only is writing this inline validation code often uninteresting (we want to get the real features like that cool video player implemented). There is also a very big maintenance issue with this approach; we are actually going to write the same validation code twice: once in Rails and once in Javascript. So now, whenever we update our backend validation logic, we need to remember to update our client validation logic as well. Wouldn’t it be great if there were a way to automatically generate our client validations based on our backend code?

Enter the shiny new (very-appropriately named) gem client_side_validations. Brian Cardarella wrote the client_side_validations gem as a result of Luke Wroblewski’s research. Check out Brian’s blog post on his gem. With a few simple lines of code, we can add inline validations to our forms. The validations are generated with the default form builder, formtastic, or simple_form. A lot of the rails model validations, including (but not limited to) length_of, presence_of, uniqueness_of, and format_of are all supported out of the box, so your forms will be making these validations as soon as you install and setup the gem. You can also add your own custom validators if what comes out of the box is not enough for your bleeding-edge rockin’ Rails application.

So how does it work? What does an application that uses this gem look like? How the heck can I use this thing with existing technologies? These are some questions your are undoubtedly asking yourself this second, and I will answer them (sort of).

How does it work?

It’s simple! The gem extends the Rails default form builder, and all you have to do is set a :validate => true option on any form_for (or simple_form_for for simple form users) tag that you want the inline validations for. The form builder uses some rails reflections on your model validations to generate some json that gets included in a script tag after your form. The json is then used by the gem’s Javascript framework to perform the validations that need to be performed.

What does an application that uses this gem look like?

I have built a sample application that uses this gem to perform inline validations on a very contrived user registration form. Here is the github source and here is the Heroku application. You can create a state in the database, then you can add cities to that state. Once you have done this, you can register with the system as a user. The state and city that you enter when registering validates against the database you create. Also, this site is very selective, and you must be born on a Monday in order to register (just to show off how date validations can work). The application is a little contrived (only aliens, or time travelers would use it), but it does illustrate some more advanced ways that you can use custom remote and local inline validators with your forms.

How does it integrate with existing technologies?

As stated previously, it integrates nicely with formtastic and simple form. The sample application also shows how to integrate with devise. Take special note of the regular expression that was added to the user model. This is necessary because the default regular expression that devise uses to validate an email address does not compile in the Javascript regular expression engine.

Check out the source.

See it in action on Heroku here.

Make sure to add your states and cities before you register! Also, I know you are supposed to be born on a Monday to use the site, but you can fake your birthday, I won’t get mad (I wasn’t even born on a Monday).

Food on the Table One Year Later

Presented by: Manuel Rosso, founder of Food on the Table

Food on the Table is revolutionizing the way families buy groceries and eat at home.

Food on the Table distills complex data into a simple product. Combines what’s on sale with what’s relevant and recipes to provide meal plans.

Customer validation with Concierge MVP: hand holding occurred with the first few customers. He went and met with customers at a coffee shop, sat down and went through the whole process manually.

The first few customers really cared, but the challenges are how to get to the next 100k customers.

Ideating can develop into grandiose ideas, but it’s critical to maintain discipline. Never lose sight of where you’re going AND be able to distill it down into what needs to be built right now. For example, the big plan was to get 35k stores pulling 1.5 million sales items, but customers only care about one store. So Food on the Table made sure their first ten users shopped at the same store. This brought simplicity by removing worry about how to scale system. Also, they learned that protein drives dinner decisions. Instead of 35k stores with 1.5 million items, they had one store with five sale items. Today, they have thirteen thousand stores with four hundred thousand items.

Don’t provide all possible recipes, just the right (simple) recipes with few ingredients. Also, provide four to five recipes for specific ingredients.

Food on the Table built up the recipe database based on five recipes being available every week for sale items.

Break down learning into small steps turning it into smaller experiments. Learn first, code last. Make leaps of knowledge with customers first.

Drew Houston, CEO and Founder of Dropbox: How We Decide What to Build

Presented by Drew Houston, CEO and Founder of Dropbox

People > Process:

- Great engineers are dramatically more productive than average engineers
- Hiring fewer but better people reduces need to be great at coordination, planning, etc
- 25 person engineering team split up into smaller, loosely coupled sub-teams
- Each with own roadmap, release cycle, process, team meetings, etherpads, tests, continuous deployment, etc.

Find great people:

- In general we don’t tell people how to work- no mandatory hours, etc.
- Make the office a place that people like to be
- Pick whatever workstation, tools (no budget)
- Minimize overhead and decentralize day-to-day decisions through culture/values
- Cofounder Arash maintains “soul” of the user experience; designer Jon keeper of look and feel

Big results with small numbers of people:

- One visual designer (formerly community manager!)
- Server team of 3 manages 100+billion files, 10+ petabytes of data, etc.
- Strategy: divide and conquer, keep teams small (won’t scale forever but has for now)
- As team grows, values/culture/mission made more explicit and deliberately taught to new people

Planning:

- We don’t do a lot of advance planning, but we need more than we used to
- Functions outside engineering
- People don’t know what other people are up to with a larger team
- Less information spreads by osmosis
- As we grow more leaders internally, they need to stop and plan for their teams
- For a while we were doing too many things and nothing would ship for months

Dropbox company goals:

- Modeled after Googles OKR Systems
- Yearly goals and quarterly goals
- Forms a hierarchy that is shared publicly
- Overall company goals
- Overall product goals
- Team goals (e.g. client team)
- Eventually per individual

Study how other companies grew:

- Challenge with scaling orgs is things that used to work start failing quietly
- “What are we doing? Why?”
- “Why does what I’m doing matter?”
- “What is most important”
- We try to learn from other companies

Launch fast and iterate quickly

- …unless you’re making pacemakers
- different sub-teams need different engineering tradeoffs (e.g. server core teams vs. web teams)
- Our most valuable asset: people’s trust. Years to build, seconds to lose

Brad Smith, Intuit: entrepreneurship in a large company

A conversation with Intuit CEO Brad Smith and Eric Ries: The Relevance of Entrepreneurship at Intuit. Brad had a number of really awesome lines, which unfortunately came off as a bit too rehearsed, so much so, that it made me wonder if there are many Intuit engineer that have a real opportunity to innovate as entrepreneurs. I still felt that he had a lot of good things to say, and I wish more big company CEOs would talk like this.

“Entrepreneurship is the heartbeat of the company. We have 8000 entrepreneurs: our employees.”
“Everyday we work very hard to rage against the machine. Big company culture will kill innovation” (via @jbollinger)

Corporate government can’t impose more than 3 rules
We don’t ask questions, we watch
Innovation is born out of constraint
A team must be able to be fed by two pizzas
Keep teams small and iterate quickly
We suffer a rich man’s disease. Innovation is borne out of constraints
The problem with big companies is with the managers, who are too used to playing Caesar.
As a leader, it is not the answers you have or the questions you have — asking the right questions at the right time in a startup team is the most important thing as a leader
Setup  an environment of experimentation
Ultimately what led Intuit to success was exposing their stuff to customers early
Double down on the stuff that  works
The culture of experiments beats the culture of powerpoint and articulation
The two most dangerous words in business are “sounds good”
Managers remove roadblocks
“Build just in time not just in case” - don’t build a multi-generational platform that will change the world
Create the environment, and let the small teams figure it out to attain success

For a new product, Brad considered it a big success to have two groups of customers: raging advocates and pissed off people
Big  companies put processes in the way of innovation. It’s not about  spreadsheets, and processes, and planning, but that’s what managers do.
The worst management philosophy is that of a genius with a thousand helpers. You have to hire people who are working closely with the customer to solve a problem you would never have solved.

Brad described a “reverse acquisition” where they acquire a company and put the new guy in charge. For example, the Mint entrepreneur took over a division that included Mint and Quicken.

Q: How to overcome internal resistance? internal employees feeling like they lost to a competitor that is bought.
A: If we didn’t invent it ourselves, it doesn’t mean we failed
Learn from startups or bring them onboard

“The greatest minds closest to the customer develop the great ideas”

Hire entrepreneurial engineers: engineers who are in love with the outcome of the science, NOT JUST the technical stuff. You have to find someone who loves watching and learning from customers

Horizon planning
- Existing business groups increase market share, increase word-of-mouth

Q: Do you plan to put more of Quickbooks online and what are your plans for growing to other countries?
A: Connected services companies are 60% of revenue
Desktop products aren’t growing

60/30/10 revenue distribution
60% to horizon 1 products, 30% to the teenagers, 10% to new projects

SLL Conference: Andy Wiggins, Heroku

The second part of our Startup Lessons Learned series covers the interesting story of Heroku’s “Epic Pivot” told by Andy Wiggins.

photo credit: Morgan Linton

6 weeks to build initial prototype

Idea: Filemaker Pro for the web (but with real programming tools)

Accepted to Y-Combinator

Soft-Launched with Ruby Inside community
Closed $3M VC round in Feb 2008
Still hadn’t found product/market fit
Had around 10-15k enthusiastic users at this time which represented a limited market

Product market fit is not adoration of users, peers, or adoption.
Development apps - can edit on the web, can’t scale up
Production apps- can’t edit on the web but can be used with git and scale up

Cutting out the Heroku Garden web editor which was initially the key user facing feature
O’Reilly Learning Rails told users to use the web editor at the same time they were cutting it out

Early success was distracting them from long-term vision

For them, cutting the web editor was the Epic Pivot. Cutting it out was an emotional heartache but eventually made life easier. Hard to recognize pivot because they were successful.

Turned past product into Heroku Garden and led users to use new Heroku product. Eventually killed off Heroku Garden

Ultimately led to an acquisition by Salesforce for $212 Million

Eric Ries: Stop Wasting People’s Time

At SLLConf this year, we decided to try an experiment of live blogging via typewith.me. The event is being simulcast to a global audience, just like last year. This is the first of a series.

Eric Ries kicked it off with an update on the Lean Startup “movement.”

Eric Ries says he’s just a figurehead, later Eric Ries referred to himself a “professional talking head”. He isn’t lean startup, we are.
We are experiencing a worldwide entrepreneurial renaissance.

Everyone turn your cell phones on! Being off the internet is irresponsible and direspectful to our ancestors who created this technology for us.

Lean Startup is global — it is no longer a Silicon Valley phenomenon. Check out Lean Startup Meetups.

We are in the process of democratizing entrepreneurship.
But, it has also been institutionalized…

  • Harvard Business School- MVP Product Fund
  • Stanford University- Lean Launchpad
  • BYU- Lean Startup Research Project

Books

  • the Entrepreneur’s Guide to Customer Development
  • Steve Blank’s Four Steps to the Epiphany
  • (and there was another one that we missed)

Entrepreneurship is not just two guys in a garage, it is a discipline

GhostBusters is one of the great entrepreneurship movies of all time
All great entrepreneurs have great stories. The movies play out like this:
Act 1) Characters& timing
Act 2) Boring stuff — the “photo montage” of people at the keyboard drinking beer
Act 3) How to divide up the spoils
This conference is about Act 2 — how does it really happen.

“A startup is a human institution designed to deliver a new product or service under conditions of extreme uncertainty.” — Eric’s definition

startup = experiment

“our future GDP growth depends on the quality and caliber of our collective imagination”

We are building companies that have fundamentally no customers and are pulled off the shelves

Frederick Winslow Taylor (March 20, 1856 – March 21, 1915) was an American mechanical engineer who sought to improve industrial efficiency.

Scientific Management:
* Study work to find the best way
* Management by exception
* Standardize work into tasks
* Compensate workers based on performance

What are we doing now that will later be revealed as myth and prejudice?

The Pivot
“better to be misunderstood than ignored”
Runway- number of pivots you still have the opportunity to make
Speed Wins

Validated learning reduces the time between pivots
Acheiving Failures = successfully exeuting on a bad plan
Why is it important to do things efficiently if we’re doing the wrong thing?

W. Edwards Deming and Taiichi Ohno- start of the Lean Revolution

Who is the customer? whose eyes matter in determining value vs. waste?

Minimize the total time through the loop
Ideas -> Build -> Code -> Measure -> Data -> Learn
see image here: http://lean.st/principles/build-measure-learn

Ship it anyways and see what happens? Why spend time agruing about the details if there the chance that no one will want it.

How do we figure out what we need to learn as quickly as possible

The Toyota Way
Foundation is long term thinking -> culture that supports people to do their best work

He displayed this pyramid:

  • People
  • Culture
  • Process
  • Acountability

“We have begun to learn how to keep innovators accountable”
Use learning milestones instead of product milestones
What are the inputs to our business plan right now
better have bad news that is true than good news that we made up
“If the 10% customer adoption does not happen, everything in this business plan is irrelevant” should be a big red banner!” via @timolehes
Tune the engine -> every business has different math

Pivot or persevere? when experiments reach diminishing returns, it’s time to pivot.

“If we alllow ourselves to fail, we can train our judgement to get better over time”

Hosted Continuous Integration with CloudBees

We’ve keeping an eye out for hosted continuous integration for some time. Recently, I heard about CloudBees from John Dunham at Sauce Labs (another great cloud-hosted service which will run your Selenium tests). It seems some ofthe Hudson folk have escaped from Oracle, renamed/forked the open source project as “Jenkins” and are setting up shop with $4M from Matrix Partners with the goal of offering a platform for hosting Java apps, including the Java-based continuous integration system, Jenkins (nee Hudson).

I’ve tried it out on one Rails project I’ve tried, I’ve got specs running, but not passing and I’m not sure why yet. Here’s what I’ve figured out so far…

export rvm_path=~/.rvm
echo 'export rvm_path=~/.rvm' > ~/.rvmrc
mkdir -p ~/.rvm/src
cd ~/.rvm/src
rm -rf ./rvm/
git clone --depth 1 git://github.com/wayneeseguin/rvm.git
cd rvm
./install
rvm reload
rvm reset
cd $WORKSPACE
rvm install ree-1.8.7
rvm use ree-1.8.7
rvm gem install bundler --no-rdoc --no-ri
rvm exec bundle install
cp config/database.yml.dev config/database.yml
rvm exec rake db:create:all
rvm exec rake db:migrate
rvm exec rake spec