Creating Links In Rails Views Using link_to

Part of rails’ magic pixie dust is delegating the annoyances of html links to the ruby on rails black box. While frustrating at times, it is ultimately a time saver. Below are many common use cases, displayed by example:

=link_to "Twitter", "http://twitter.com/#!/wmilesn"

This is about as easy as it gets. You’ll end up with a nice href that spits out the html:

<a href="http://twitter.com/#!/wmilesn">Twitter</a>

Now let’s spice it up a bit. Let’s say I want to add an additional html attribute to the link:

=link_to "Twitter", "http://twitter.com/#!/wmilesn", :target => "_blank"
#you can add as many attributes as you want, separated by commas and after the first two parameters
#while I am using strings for my values, you can use any variable you'd like, such as @product.price
<a href="http://twitter.com/#!/wmilesn" target="_blank">Twitter</a>

Hold on…this looks great, but what if my attribute has dashes or other non-ruby-esque kryptonite characters?

=link_to "Twitter", "http://twitter.com/#!/wmilesn", :target => "_blank", "data-role" => "button"
#just surround the attribute with quotes
<a href="http://twitter.com/#!/wmilesn" target="_blank" data-role= "button">Twitter</a>

…and for the match point, an image within a rails link

=link_to(image_tag("splash_banner.png", :alt => "Home Polish Banner", :id => "splash-banner"), twitter_link, :target => "_blank")
#note: in almost all cases parenthesis are optional, but here they're needed
<a href="https://twitter.com/#!/homepolish" target="_blank"><img alt="Home Polish Banner" id="splash-banner" src="/assets/splash_banner.png"></a>
<!-- now that's time saving, eh? -->

A discussion of rails links wouldn’t be complete without touching upon some of the built-in ruby on rails variables that can be used to avoid having to worry about absolute url paths in development versus production and to handle all of the messy details around specific database entry numbers

#/views/products/show.html.haml
=link_to "Buy this product", @product
# @product model instance is defined within the /controllers/products_controller.rb
<a href="https://YOURHOST/products/PRODUCTID">Buy this product</a>
<!-- Rails will automatically drop in YOURHOST and PRODUCTID -->

The idea here is that the controller passes along a product record from the database, and rails’ link_to function is smart enough to extract the relevant information to create a fully formed path. Note: including just @product is a shortcut rails uses to guess that you mean you want to link to the products#show view. You can also specifically reference certain properties of the record, such as @product.external_url and grab either the relative path @product_path or the full url @product_url. These are all equivalent:

=link_to "hello", @product
=link_to "hello", product_path
=link_to "hello", url_for(@product)
=link_to "hello", product_url
# the only differences arise between _url and _path when you are running on different server environments or linking externally, since _path will only return what's after the domain suffix, such as PATH within http://wmilesn.com/PATH where url will return the entire url. In most cases, both will send you to the same place.
<a href="/products/38">hello</a>
#where 38 is @product id field

If you want to dive deeper into the magical rails object variables, I’d recommend running

$ rake:routes

to see what’s available, and reading up on the topic here.

*NOTE: ALL VIEWS ARE WRITTEN IN HAML (a space-delimited html-template markup language)*

How to Install a New Ruby On Rails Gem

Let’s start with a sample Gemfile:

source 'https://rubygems.org'
gem 'rails', '3.2.3'

group :development do
  gem 'sqlite3', '1.3.5'
end

group :production do
  gem 'pg'
end

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'
gem "haml", ">= 3.1.4"
gem "haml-rails", ">= 0.3.4", :group => :development
gem "rspec-rails", ">= 2.9.0.rc2", :group => [:development, :test]
gem "factory_girl_rails", ">= 3.1.0", :group => [:development, :test]
gem "email_spec", ">= 1.2.1", :group => :test
gem "devise", ">= 2.1.0.rc"
gem "cancan", ">= 1.6.7"
gem "rolify", ">= 3.1.0"
gem "uuidtools", "2.1.1"

There’s a lot going on here, so let’s break it down:

  • gem "rolify", ">= 3.1.0" is an example of a gem that loads in all environments (development, test, production)
  • gem 'pg' on the other hand, is only going to be loaded in the production environment (along with everything else you put inside the group :production do section
  • gem "rspec-rails", ">= 2.9.0.rc2", :group => [:development, :test] is an example of the most complicated of the bunch, because it’s both specifying that only versions greater than or equal to 2.9.0.rc2 should be installed, and also that it should belong to both the development and test group (that way you don’t have to repeat it in both groups above)

Now that you have the proper gems in place, run

$ bundle install

from the command line within your app’s directory and remember to restart your server!

p.s. In some rails tutorials, you’ll see people add require GEMNAME to the top of files where gems are explicitly referenced. This is no longer necessary, so don’t do it.

One more tip. Some gems, like uuidtools require special consideration when calling its functions:

#/controllers/products_controller.rb
//...
UUIDTools::UUID.timestamp_create.to_s
//...

In this example, I’ve explicitly called the timestamp_create function within the UUID class and UUIDTools module by using double colons :: to let rails know that I want to access this function within a file contained elsewhere (i.e., in our gem bundle)…no require required.

Master Ruby on Rails Rockets =>

In Ruby on Rails, you’ll often see some knarly character codes when dealing with hashes. Do not be afraid, they’re actually quite simple. Here’s how to map the concept from javascript to ruby:

#RUBY
promLink{:href =>'http://twitter.com/#!/wmilesn', :target => '_none'}
//javascript
var promLink = {
  href: 'http://twitter.com/#!/wmilesn',
  target: '_none'
};

No too terrible! In fact, it can get even simpler, because in the newest version of Rails 1.9.3, you can even use javascript’s hash syntax within rails. Yep, this works as well:

#RUBY
promLink{href: 'http://twitter.com/#!/wmilesn', target: '_none'}

…just be careful, because variables elsewhere will still be prefixed with a ‘:’

Node.js versus Ruby on Rails

Unlike many in the developer community, I started out toying with Node.js, and then dove into Ruby on Rails via the delightful Rails for Zombies followed by Michael Hartl’s Ruby on Rails Tutorial. The result is an unscientific comparison of (Javascript on) Node.js vs Ruby on Rails.

Node.js is not a framework!

First things first, Node.js is a server bundled with low-level routing and sysadmin capabilities and written in Javascript. To even begin this comparison, Node.js requires some friends in the form of Express.js and Mongoose (should MongoDB be your database of choice) to align with Rails, which is written in the Ruby language.

Ruby is like a crotchety old man with a heart of gold

Now that we have that out of the way…next up is the language. Node.js is written completely in Javascript, while Rails is written in Ruby. In learning both, I find pros and cons for each. On the benefits side, Javascript has an easier syntax to pick up quickly, since you probably know some from front-end coding (as opposed to Rails’ :VARIABLE => hash-bangi-ness, the fact that functions don’t require parenthesis, VARIABLE do |iterator|, :: namespace resolution, < class declaration, and @local parameters borrowed from Perl). However, Ruby can be more succinct and does not require a forrest of brackets to work its magic (coffeescript readers out there, calm yourselves…). Additionally, Ruby (and rails) comes packed with extremely useful built-in functions surrounding everything from dates (think syntax like 10.minutes.ago) to "string".squeeze and ['array' 'elements'].include?('array') #true. Yes, Javascript can accomplish all of this, but it requires some know-how and a few custom prototyped methods…or something like _underscore.

100% Javascript Rocks, but is ultimately overrated

With the languages out of the way, we can turn our attention to actually building web applications. Node.js shines because it enables a front-to-back Javascript environment, where in Ruby you’re forced to contend with SQL, Ruby, and Javascript. While seemingly a superior and streamlined experience, after playing around with both, I’d put the value in the ‘overrated’ category. It really isn’t hard to pick up on Ruby once you’ve ready a number of sample programs and a few blog posts. Additionally, with Ruby, you can almost completely forget about callbacks and the nested soup that Javascript brings to the table because of it’s non-blocking architecture (which I do realize is a plus for certain performance gains).

Rails gives you the full package

Putting languages and stacks aside, Node.js + Express.js offers routing along with free-form controllers, views, and helpers. These tools pale in comparison to Rails. To make an analogy, Rails is to Node.js + Express.js what Muji is to American Apparel. Both will get you clothing and home accessories, but American Apparel’s clothing looks kind of wonky, doesn’t always have what you need, tries to be a bit too cool for its britches, and doesn’t always play nice with other items in the store. Muji, on the other hand, has obsessively designed products that were seemingly cut from the very same cloth.

To get back to programming…Rails comes with a fulsome ecosystem from models to views, controllers, to data object models (which are mostly hidden btw), with extremely clear and concise interactions that can only occur with crazily OCD vertical integration. Two examples: url_for and image_tag. url_for is a built-in function that will always provide the url for a given data object, such as @products, and image_tag pulls in the correct image url from the asset pipeline. While the same is possible with Node.js, it would require some heavy module interaction and helpers. Additionally, in rails, you just don’t need to worry about your data models. While Mongoose on Node.js helps, it’s still tough to really feel like you’re fully taking advantage of easy access like the Product.find(params[:id]) that are easily available throughout your Rails application, modules, controllers, and views.

However, it’s important to note here that these integrations do come with a downside.  Often I feel like I’m guessing at the ‘correct’ way to do something, always missing out on the most efficient way.  Additionally, when something goes wrong, it’s quite a bit more difficult to find out why, since Rails will read into specific variable names, like how you can add _path to new_product_path and have it magically turn into a function that returns the appropriate path for the `new` route within the product controller/model. With Node.js, what you see is what you get, and there is very little interpolation.

More people make and improve Rails modules

Next up is the ecosystem. While Node.js has an excellent start with NPM, the dust hasn’t settled on the most popular packages for various needs (the number of contenders is starting to get overwhelming).  I often feel like I’m clodging together a broken vase with superglue.  Rails, on the other hand, has one of the most robust (and free) sources for libraries and tools. I love The Ruby Toolbox, which actually shows you the relative popularity of Rails tools broken out by function. Additionally, as I mentioned before, many modules that would have to be hand-picked in Node.js are integrated by default in Rails. Stuff like database connectivity, concatenation, cache-busting, database migrations, data models, routing, and testing, etc… It even comes preset with a favicon.ico! These may seem like trivialities, but they’re all 100% necessary…and it’s nice not to have to wade through error messages from conflicting Node.js modules that don’t want to talk to each other at 12am. Layered on top of the modules are more tutorials and examples than one can typically find with node.js. Case in point, Railscast‘s 300+ video tutorials. Although, be forewarned, Rails has been around longer and seems to change faster, so many of the tutorials are out-of-date…or in some cases workarounds for features added after the article was written…as a result, it is prudent to use Google’s date selector for articles < 1 year old and start your search with Rails Guide.

Rails includes a jet pack, standard

Finally, assuming you have equivalent frameworks, database, and modules all set up, Node.js just takes much more time to string everything together (again because of the disparity in 3rd party plugins and lack of any inherent structure). In rails, putting together a complete RESTful interface takes one command line input for all of the controllers, views, and database models. rails generate scaffold Post name:string title:string content:text #and you're done
In many cases, it’s 1 minute versus 1 hour (which adds up if you have 4-5 database objects to contend with). It’s not necessarily hard work, but very prone to typos and simply a lot to remember. I don’t see myself always using Rails scaffolds, but for simple prototypes, it’s unlikely there’s a faster alternative.

In Conclusion…

Node.js is a great set of tools that are hip, growing rapidly with a dedicated userbase, (debatably) high performance, easy(er) to pick up, and better than most other web building apps out there. However, it’s really just a talented high school track star to Ruby on Rails’ Olympian. No offense to Node.js, but who would you rather train with? If you can get over the pain (and annoyance!) of learning Ruby, the choice is clear.  Remember, at least for me, the best tools are the ones that help you launch better and faster.

Having some fun with jQuery $.Done() | a.k.a., A Romantic Tale of Deferrals and Promises

Valentine’s day is just around the corner, and in the spirit of this grande holiday of flowers and chocolates, I’ve decided to tell the fictional story of how Alice and Tommy met, fell in love, and lived happily ever after.

However, as in real life (and coding), the devil is in the details. We’ll use this post as an opportunity to explain how jQuery’s .Deferred() and .Promise() functions act as our couple’s cupid.

Like many a pair, our heroins first meet at a dance club, and Tommy summons the courage to ask for Alice’s number.

A few days later, Tommy tries to give Alice a phone call:

But we’ve got a problem… Tommy wants to wait a day before calling Jenny, but our javascript is calling her immediately (even before he has her number). Lame. This is the result of javascript’s asynchronous runtime and also happens to be a common confusion with javascript compared to other ‘blocking’ languages (but also, as you’ll see, one of it’s many benefits too). The good/bad news is that it’s also the fundamental building block of ajax, since you often need to find a way to execute certain javascript code while waiting for the server to respond to and then execute other functions.

jQuery to the rescue! What we need to do is find a way to let our code know that the phone number was received before trying to dial it. There are a number of ways to accomplish this, some less elegant than others (nested functions I’m talking to you…cough, cough). Luckily, jQuery has an object called .Deferred() that helps smooth the process:

Here’s what’s going on:

  • We create a jQuery .Deferred() object called seeYouAgain
  • The danceParty() function is called
  • The danceParty() function waits 1 second to let seeYouAgain know that it should act on the phoneNumber
  • seeYouAgain is notified of the desired act and calls the phoneCall function with the number provided
  • After phoneCall works its magic, seeYouAgain resolves itself, which calls the .done() function with the response from the phoneCall function
  • We have a date!

The first date (and a few more) went swimmingly, and Tommy decides to make his move:

Unfortunately for Tommy, Alice is a classy girl and needs a few things before the fun can begin.

Here’s what went wrong for Tommy:

  • We created a letsGetItOn deferred object similar to seeYouAgain
  • jQuery’s when() function calls the wantToComeUpForANightcap() function, then calls the then() function with the bad news returned from wantToComeUpForANightcap()
  • Additionally, the letsGetItOn promise is rejected, and the letsGetItOn.fail() function displays the mood

Tommy realizes he needs to tone-down the creeper factor, then they then fall in love and live happily ever after:

Here’s what’s going on in the javascript (as if anyone even cares at this point):

  • jQuery’s .when() function calls putARingOnIt(), fallInLove(), and weddingDay(), and collects promises from putARingOnIt() and fallInLove(). A promise is essentially a placeholder so jQuery knows what to do when the letsGetItOn deferred object is resolved.
  • However, jQuery doesn’t actually alert a message until letsGetItOn.resolve() has been called by weddingDay()

The End.

Solving the mystery of Chinese numeric domains: 3309.com, 4399.com, 17173.com, 126.com…

In America it would be unheard of to name a newly minted Internet startup with a numeral. Just imagine the TechCrunch article “1423.com is the next Tumblr!” But, for inexplicable and intriguing reasons, many highly-traffic Chinese Internet startups do just that.

Here are some examples: 115.com (30K monthly uniques), 39.net (23K), and the mother-loads, 163.com and 56.com with over 235,000 monthly uniques a piece. It’s too tantilizing a conundrum to ignore, so I’ve begun an investigation with the following hypotheses:

  1. The numbers correspond to Chinese characters via Unicode or other encoding schemes. This was my original thought, but after digging through the painstakingly opaque and murky details surrounding Chinese character encoding, it is unlikely to be true. First, Chinese unicode characters when converted from Hexidecimal to Base-10 start in the 19,000s. Second, I thought I was on to something with CCC, the Chinese Commercial Code, but alas, my first test of 3309.com yielded the character 溲 , which translates to “urinate” and is unlikely to have been selected during late-night brainstorming.
  2. The numbers are considered lucky in Chinese culture. I like this hypothesis, but was unable to find much support for it using this map from lucky numbers to phrases and a bit of Wikipedia. The only site out of all mentioned in this article that had a match was 39.com, which means “Thank You.”
  3. Numbers are inherently transferable across cultures / dialects. A 1 is a 1 is a 1 in nearly all European, American, Chinese, and Russian languages. Maybe they wanted english-speaking VCs to recall their domains without memorizing Chinese characters (or figure out a way to type them into the browser…).
  4. In China websites are more akin to phone numbers. I have no idea if this is correct, but perhaps culturally the Internet is perceived more like a giant phone book.
  5. Chinese characters are not allowed by .com domain registrars due to ICANN restrictions. This may be one of the stronger arguments, since .com has historically only allowed ascii characters. However, recent advances in International Domain Names (IDNs for short) now allow for multi-language implementations. Perhaps many Chinese companies were started before this breakthrough and are concerned about changing their names, or they are weary of the fact that IDNs require modern browser support and and conversion into ASCII via Punycode.

*UPDATE* A good friend with mad Chinese skills provided the following explanation, case closed:
“it’s mostly that the numbers are a close homonym for chinese words that mean good thing:

168.com –> 1 (yi) 6(liu) 8 (ba) ~ 路發(yi lu fa) == be prosperous all along

163 is similar –> 3 (san) ~ 生 (sheng) == birth, life

17173 (yiqi yiqi san) == yiqi also means together 起”

Avoiding pitfalls when setting up Heroku for Node.js on Ubuntu

Heroku has an excellent introduction to deploying your first node.js project on their PaaS-tastic Cedar stack. However, there are a few key points to keep in mind:

  1. If you’re new to Heroku and focused exclusively on Node.js, then you’ll likely be developing on Ubuntu and need to install the Heroku command-line client. You’ll find instructions on what to type into the console here. However, if you’re using a default Ubuntu install, then you’ll probably need to use the sudo command on these…and you may get an error when typing in the second line

    $ curl http://toolbelt.herokuapp.com/apt/release.key | apt-key add -

    that says

    $ % Total % Received % Xferd Average Speed Time Time Time Current
    Dload Upload Total Spent Left Speed
    100 2442 100 2442 0 0 2273 0 0:00:01 0:00:01 --:--:-- 5856
    gpg: no writable keyring found: eof
    gpg: error reading `-': general error
    gpg: import from `-' failed: general error
    

    This is an easy one to fix, and is simply a permissions error on the apt-key program. Try this code, and it should work

    $ curl http://toolbelt.herokuapp.com/apt/release.key | sudo apt-key add -
  2. Next, after a seemingly successful install of the Heroku command-line client, when typing in

    $ heroku login

    You might get back

    $ /usr/bin/env: ruby: No such file or directory

    This is because Heroku requires Ruby to run. Luckily, again, an easy fix…just make sure not to install more than you need (i.e., you definitely don’t want to install Apache or Ruby servers, etc.) if you stumble upon this site. This should be the only installation you need to get going

    $ sudo aptitude install ruby build-essential libopenssl-ruby ruby1.8-dev

The Internet No Longer Belongs to America

At 6 years old, I was one of Internet’s first million users. Prodigy was the ISP, MADMAZE was the hook, and my father’s word processor was the hardware. I had no idea that the service overcharging my parents by the minute would evolve into one of our civilization’s defining advances or that millions of additional users would come online within the next few years. I just knew I liked it. A lot.

The U.S. is in a similar position today, having witnessed the Internet’s creation and spurred it’s adoption rates north of 80%. However, also like my experience, there are billions of people behind us in line to go online. Even today, over 88% of Internet traffic comes from outside the U.S., and there are nearly double the U.S. Internet users in China. Over the next 5-10 years, the U.S.’s traffic will continue to shrink towards less than 4% globally. We are, and will increasingly become, the minority within our own creation.

I can’t help but think about the ramifications of such a global transformation. Here are my initial thoughts, I look forward to hearing yours:

  1. We’ll be seeing most Internet innovation occurring outside the U.S. Silicon Valley/Alley are the dominant taste makers and dollar directors in today’s Internet market, but this must change. It’s simply a numbers game. You don’t seriously think that out of a pool of 6 Billion people outside the U.S., a team of 5 hackers with comprehensive, free, and enterprise-grade programming tools at their disposal won’t come up with a Facebook. Come on, be real (and take a look at Herman Chinery-Hesse, the “Bill Gates of Ghana”). As a supporting side-note, consider that Stanford’s free Machine Learning online course has over 50,000 participants, and it’s clear most aren’t from the U.S.
  2. The Internet will be composed of far less English language content (but we won’t notice). Facebook generates over 100MM wall posts each day, presumably largely in English. The rest of the world will catch up and likely start posting over 15 Billion non-English messages PER DAY. To get a sense for that number, it’s like posting a Library of Congress’s every week. But you’ll never know, because Facebook and Google will take great pains to hide all of this from your search and browsing experience. This is a shame, as think about how much knowledge, joy, and connections could be made around the world.
  3. Innovation will scale rapidly and globally. It will become nearly impossible to hide great ideas or services, and a connected world will react instantaneously, with each region adding their unique cultural touches. This will cross the lines of science, publishing/advertising, politics, and technology. Consider how we found out about Haruki Murakami or that #occupywallstreet spread across the world within a few weeks. I would also be remiss not to mention China’s growing seed investment funds.

That’s just a taste, I’ll continue to think of more…

Why we keep seeing trivial “me-too” Startups

Jon Evans of TechCrunch recently described the perils of “Startup Alley’s large numbers of trivial, me-too apps, all too often marketed as “Airbnb for X” or “the gamification of Z” or “the business card … reinvented!” Here’s my take on why this is happening (and it’s not pretty…):

  1. In today’s fundraising environment, an offshoot of another product is the safest investment decision a VC can make. The idea is understandable by mainstream audiences, the virality is proven, the audience base is already in place (if only shifted 10 degrees to the left), the costs and mental effort to create such a product are fully scoped, the founders have prior successes, and key technologies are bootstrapable upon crumbs of innovation tossed to the masses by the Majors. The risk of failure is still considerable, but it is as well defined as possible. This is, of course, at the expense of game-changing innovation. Kind of like playing Skee Ball by always shooting for the 10 ring.

    We see this occuring because truly epic visions sound completely insane when first presented. It is unlikely anyone (even the founders) grasp the extent of their idea’s brilliance or have any conception of what it would really take to succeed until after the fact. The only answer a VC can give when constrained by logic, investment caps, and committees is to demur with a polite “come back when you have traction.”

  2. Most of today’s founders are no longer insane. I don’t mean insane in the clinical sense, but somewhat demented enough to dig a hole to China from San Francisco (with shovels) confronting the daily threat of failure with no end in sight. A willingness to throw caution to the wind, completely ignore rationality, and strike out on your own to realize a vision so far from normalcy that it would be tantamount to describing color to the blind. To do this, you pretty much have to be outside of the global talent funnel and either unable to get a cushy job or insane. This rarely occurs today, but was the norm just 50 years ago.

    Two generations ago, educational and societal constructs made it much easier for the right type of person to go insane and chase wild dreams. The means of properly assessing and funneling talent to it’s optimal (and terminal) vocation were marginal at best, and the motivation for absolving yourself of your current lot in life was quite tempting (and in many cases the only option to survive).

    Today, the economic “invisible hand” is stronger than ever before and bolstered by social media outlets and advanced number crunching. The chances of going insane due to a mismatch in talent are much lower. In this environment, an intelligent go-getter has a high likelihood of being snapped up by one of thousands of global companies that actively devour talent. The pay is good, social approval is adequate, the career prospects are painted a rosy red. In essence, the entrepreneurial failure of settling has become too seductive a concubine for the most potent entrepreneurs of our generation.

Let’s take a look at a few examples of game-changing innovation that would never occur today:

The Handheld Camera. In 1868, George Eastman started his career as a messenger boy with an insurance firm being paid $3 per week ($57 in today’s dollars!). He then went insane during this time period and started tinkering with obscure British chemical research papers. By 1880 George became convinced of a vision to “make photography an everyday affair…and as convenient as the pencil.” Keep in mind that at this time a camera was as big as a microwave oven and required a heavy tripod.

Soon after launching his company, he “expected that everybody who used glass plates would take up films, but found that the number which did so was relatively small.” It took an even greater leap of faith by guessing (correctly) that “to make a large business we would have to reach the general public.” This sounds obvious today, but it was a huge risk as people did not take their own photographs at the time (and many were weary of even having their pictures taken at all).

The Television. Philo T. Farnsworth was 20 years old in 1926 when he conceived of the TV we know today. He was mowing the lawn at the time. In Idaho. On a farm. If Philo wanted to escape the farm, he had to entrepreneur his way off of it. “Farnsworth worked at odd jobs until he met a willing investor who lent him money to start building his television.” There was no such thing as a Thiel “don’t go to college, go to work” fellowship, the Intel Science Talent Search, or lucrative Wall Street jobs tugging away at his innovative powers.

Quickly, however, the development of his television was plagued by lack of money and challenges to Farnsworth’s patent from the giant Radio Corporation of America (RCA). While never making a fortune, Philo’s technology still ended up in millions of televisions across the world.”

Xerography. A Queens-based patent attorney named Chester Carlson succeeded in bringing Xerography to bear in 1938 after obsessively frequenting the New York Public Library to read the research papers of Hungarian scientists. At night he would tinker with prototypes in his kitchen. “I had my job,” he recalled, “but I didn’t think I was getting ahead very fast. I was just living from hand to mouth.”

We take photocopies for granted, but from 1939 to 1944, Chester’s idea was turned down by more than twenty companies. Even the National Inventors Council dismissed his work. “Some were indifferent,” he recalled, “several expressed mild interest, and one or two were antagonistic.” It was only until 1947 that he entered into an agreement with a small photo-paper company called Haloid (later to be known as Xerox) and enjoyed the ensuing billions of dollars that came his way.

In contrast to these examples, today’s entrepreneurs are climbing out of the hole to China and settling by digging the comparatively plush ditches for expanding railroad tracks. Ground-breaking innovation is becoming buried under the weight of spiraling opportunity costs, and the constraints for backing “insanity” are exorbitant. As a result, most of our generations’ best and brightest increasingly avoid the big ideas in favor of six-figure jobs with one-figure job satisfaction.

Working on Wall Street can make more sense than raising millions for your Startup

It’s all over the news these days: “VC invests $1.5 Million in [insert one-syllable nonsensical word here], founded by [3 guys in a garage]“. It seems like a lot of money to play with and the opportunity of a lifetime, but (if you have a job) the salary you’re making might end up being more lucrative.

We can use some financial math to compare a stream of payments over time (i.e., your salary) and a lump-sum cash deposit (VC funding). Let’s take NYC’s median salary of $50,820 and analyze how it would compare to a $1.5 Million VC investment for a team of 3:

  1. We’ll assume for the purposes of this article that both a Startup and a salaried position take up all of your “productive” time, leaving the few remaining hours for sleep and other extracurricular activities.
  2. The average VC investment horizon is 5 years, which for 3 NYC median salaried folks would equate to a payment of approximately $660K today. You can essentially think of this amount as grouping all the salary payments together and adjusting downwards to account for the risk you get fired and can’t find another job. If you’re bright and your company is stable, the risk is probably just above inflation.
  3. This $660K fundraising event is actually the likely outcome for ~25% of Startups that successfully raise money…and it’s important to keep in mind that only 18% of Startups ever raise money.

So the next question is what your salary would have to be to match the aforementioned $1.5MM investment. It turns out to be $115K…which is about the same as a first-year investment banking analyst fresh out of college.

The wild-card in this analysis is that a Startup can be sold in the future for much more than the initial investment. But after dilution and factoring in that most Startups fail (or at the very least never recoup their initial investment), it may not really be a significant variable to consider. As a point of reference, according to a recent review of Internet transactions, only 152 deals closed last year (out of 73,000+ companies in Crunchbase).

There you have it, that amazing million dollar investment may not be all that much better than a high-paying job on Wall Street. Before you all freak out and start trolling, obviously there are other important considerations like how much you enjoy the work and future prospects after the 5 year horizon. Personally, I see arguments on both sides.

UPDATE: This article was posted on both Hacker News (here) and Wall Street Oasis (here). We’ll see who comes out on top.