1. FAIL: Your name is invalid. (Ruby UTF-8 regex)

    Often times you’ll want to validate users’ names (or nicknames) in your web applications.  Although I’m not fundamentally opposed to using all the wonderful Unicode (UTF-8 in particular) characters under the sun, it does make it easier to use and understand an app when user names are at least recognizable to you.  If an app is global (like twitter) this may not be the case.  But you get there organically, and it doesn’t make sense to open the floodgates right now.  So we started with

    validates_format_of :nickname, :with => /\A[a-zA-Z0-9_\.\-]+\Z/
    

    Allowing lower and uppercase letters, numbers, dot, hyphen and underscore.  A pretty standard start.  But we saw some validations fail when user names were copied from 3rd party services (twitter, facebook, tumblr) including some letters with accents over them.

    Fortunately we are using Ruby 1.9 (with Rails 3.1) and validating with unicode is straightforward.  We added support for all the Latin extensions with just two tweaks.  First, we need this at the top of the file with the regular expression so Ruby interprets it correctly

    # encoding: UTF-8
    

    then we add from code point U+00C0 to U+02AE, chaning our regex to

    validates_format_of :nickname, :with => /\A[\u00c0-\u02aea-zA-Z0-9_\.\-]+\Z/
    

    Once we get bigger in countries that speak other languages, I’ll be adding some more characters sets to that regex.

     

    tags:  utf-8  unicode  ruby  regex  fail 

    Comments
  2. On Failing at Hackathons

    Tech Crunch Disrupt was another success this year.  Sadly, I didn’t get to go.  Myles, Henry and myself entered the TCDisrupt Hackathon last weekend, hoping to crank out something brand new, present it, and get some free tickets.  That didn’t happen.  There are a few good reasons why we didn’t present.  That was my first hackathon, and these are my learnings…

    Don’t Learn New Technologies

    We built our project on Rails 3.1 beta 1.  There are some great new features (better asset management via sprockets, SASS, CoffeeScript) I was excited about.  We already use SASS, and decided to skip CoffeeScript, but it still took almost an hour to work through the bugs with sprockets and get Rails 3.1 working on all of our machines for the first time.  While it was a good learning experience, it would have been much more efficient to stick with Rails 3.0.5 that we all already had running on our machines, VMs and servers.

    APIs love hackers love APIs

    It’s no coincidence API vendors dominate hackathons: leveraging API’s is an incredibly powerful way to build on an already existing user base and deliver impressive results in little time.  If you’ve already hacked with a given API that’s another huge plus.  But even if you haven’t, the good ones have great docs.  Use APIs, you’ll be standing on the shoulders of giants!  We didn’t use any API’s.  While this didn’t hinder us, it also didn’t help.

    Get Started Early

    Hackers are generally moral and fair creatures.  So, if it’s a 24 hour hack from start to demo, we probably won’t start coding _on this hack_ beforehand.  But if you have some libraries or code you’ve written for other purposes that can be incorporated, there’s nothing wrong with that.  It’s also a good idea to really think through your hack - the architecture, the problems that may arrise, the difficult bits, how to split up work, what to names things* - and plan it all out.  Although no plan survives contact with the enemy, there is great value in the act of planning.  Do it, and start it early.  We rushed this phase of the hack, and combined with overconfidence (a requirement of both hackers and entrepreneurs), that really came back to bite us.

    Physically Stay There

    Even though you’ll be mentally checked out at times, plan on “sleeping” there.  Don’t be a bitch.  <Arnold>Stop whining.</Arnold>  And don’t leave after 5 hours on day one to drive an hour away, go out and drink, drive back, sleep, and return on the final day for 3 more hours (a slight mistake made by yours truly).  This also relates to my next lesson learned…

    Understand The Working Hours

    As hacker-friendly as the NYC startup community has become, there’s nothing like setting your inner nerd loose without any concern of judgement when you’re in a hanger filled with a few hundred other hackers (most of whom stank worse than you, or so it seems).  Be prepared to talk shop.  Then there’s also all the “hello”s, the pretending to remember you “what’s up buddy”s, the “of course we’ll use your API if you give us free junk”, tweeting at folks who are across the room from you, checking in, hashable’ing, instagramming, and color’ing (haha, nope!).  Bottom line is, you don’t have as much time to code as you think.  Especially not during the first couple of hours.

    Have a Strong Team

    We actually got this part right.  The three of us work really well together and communicate smoothly.  It may have been cool to join up with more folks, but they’d have to fit into the puzzle correctly.  Flying into a hackathon solo is difficult, and less likely to result in something with legs.

    For us, although we didn’t get our hack to a demo-able point, we definitely consider the weekend a success.  We learned about some great new libraries and frameworks, and thought through some fairly difficult technical challenges.  It was also a fun time hanging around with other hackers coding their asses off and just being a part of the community.  We’re certainly stronger after that workout.

    * There are only three difficult problems in computer science: 1) Naming stuff.  2) Off-by-one errors.

     

    tags:  hackathon  fail 

    Comments
  3. There’s a Van de Graaff generator under your hood

    …or at least there could be.

    My brother, a solid mechanical engineer and muscle car devotee, was diagnosing an engine problem and asked me what I though.  A customer at his job was reporting sparks coming from one of the pulleys on the front of an engine.  This had been seen only a few other times, and the theories my brother heard were just entertaining.  The customer had no idea what was going on, how to fix it, or whose fault it was.

    When I learned a little more about the engine, and the pulley in particular, it became quite clear what was going on.  The pulley, normally a solid circle of metal attached to the engine via a metallic shaft, was made of two separate metal pieces; an outer metal ring and and inner metal pulley, separated by a dielectric (rubber, in this case).  If the belt was slipping on the pulley, an electrostatic charge could build up on the outer ring.  The charge would have no way to dissipate like it would on a normal pulley.  This charge could then arc to the engine block when it was strong enough (which isn’t too difficult, as the block and the pulley are fairly close).

    So my brother went on site and sure enough, the belt was loose.  A quick touch with the multimeter confirmed that the pulley was acting electrically as a capacitor, and a new (correctly tightened) belt fixed the issue.  What’s interesting is that at some point, a mechanical engineer added that rubber ring as a damper without realizing the electrical implications under a common failure mode.

     

    tags:  engineering  cars  fail  mike 

    Comments
  4. Don’t mark my app’s email as SPAM

    Judging by the number of email outsourcing companies, there is clearly a large problem to be solved.  I’ve had sporadic issues with email being marked as SPAM with HomeField, and then regular issues on my latest project, FoundersCard.  I’ve finally got them fairly well sorted, as far as I can tell…

    1. The DNS records on your name sever must be setup correctly (and verified)
      1. The A record of the domain you’re actually sending mail from (i.e. teamhomefield.com) must point to the IP of the actual server sending the email (in this case 8.12.42.205)
      2. You should also configure the SPF record which is being used increasingly by recipient mail servers to further determine if the sending servers IP address is authorized to send email for the given domain.  My DNS has a TXT record with the value “v=spf1 a mx ptr ~all”.  
    2. rDNS (reverse DNS) must be setup
      • On the server sending the mail, the PTR record must correctly specify the hostname pointing to this sever (teamhomefield.com)
    3. Your Rails setup…
      • You can set from to be any username at the domain configured above, but I’ve found that GMail will mark SPAM unless the following format is used
        • from  ”anything@teamhomefield.com (Anything Else)”
        • Not sure why “Anything Else <anything@teahomefield.com>” doesn’t work..
      • The reply-to is great for sending on behalf of a user
        • reply_to “Dan Spinosa <spinosa@gmail.com>”
      • I am using the following ActionMailer configuration
        • config.action_mailer.sendmail_settings = {
            :location       => '/usr/sbin/sendmail',
            :arguments      => '-i -t'
          }
    4. Your emails content…
      • If you’re sending HTML email, be sure to send it as a multipart email including a text part that closely matches the HTML (which, BTW, should include <html> and <body> tags)
        • In Rails, if your mailer action is named “notify_email”, Rails will automatically create a multipart email for you if you have multiple views: notify_email.text.html.erb and notify_email.text.plain.erb
      • It’s free to check your spam score & deliverability at contactology
    5. Your mail servers IP…
      • Make sure it is not listed by Spamhaus, and remove it if it is.  It is common to see your IP in their PBL, which can easily be remedied.

    HTH, and hope I don’t have to deal with this again.

     

    tags:  SPAM  rails  GMAil  fail 

    Comments
  5. Confusion Over Configuration

    Many Ruby on Rails decisions are guided by the motto “convention over configuration.”  This makes Rails opinionated software and allows one to get up and running quickly and easily, so long as you follow the crowd.  I love this.  It makes you confident you can try something new, get it up and running fairly easily, then start adding functionality, breaking and tweaking iteratively.  They so to err is human.  It’s also Rails…

    I’m a very organized person; it helps me get things done.  So when I recently started building some Rails billing functionality, I decided I would namespace it.  Shouldn’t be too bad…

    script/generate model billing/Account ...

    This created the model Billing::Account in the file models/billing/account.rb.  Nice.  Turned out to be less-than-nice when I tried to start working with it.  I’ll spare you the details of how much I hated my life that day and get straight to the caveats:

    1. The migration generated created a table called “billing_accounts” which seemed correct (and great!) to me.  But ActiveRecord doesn’t care about your namespace, so you have to manually add “table_name :billing_account” to the Billing::Account model.
    2. For testing, a new directory was created: test/fixtures/billing, but it was empty.  The file billing_account.yml was added to the base fixtures directory.  Don’t do what I did and move that file into the billing/ directory: those fixtures don’t get loaded.  So leave it, or move it and update Rails’ load path to look through fixtures/ recursively.
    3. Foxy fixtures do not work with namespaced models.  Not at all.  If there’s a way to get them to play nice, I couldn’t figure it out before deciding to hand out a couple of id’s manually.  Fuck it, that’s why.

    It puzzles me that Rails’ generator seems to handle namespaced models so gracefully, but actually creates these incompatible time-sucking gremlins.  Did I do something completely wrong here?

     

    tags:  rails  fail 

    Comments
  6. On Over Engineering

    During our meeting with Fred Wilson last week he mentioned something fairly obvious about our company: we have too few engineers  (i.e. just me).  He was making the point that one particular path for our company could see it thrive (netting a few million a year in profits) with a small 10-12 person staff (7 engineers or so).  But it started me thinking about it from the other angle: what if we had too many engineers?

    I firmly believe one of the reasons startups create some of the most beautiful and expertly crafted products is that they have limited resources with which to produce them.  Startups therefore, by necessity, build only to create value and build the smallest solution possible.  This viewpoint is bolstered by 37signals’ Getting Real, Paul Graham in many of his excellent essays, and the principle of least effort (or path of least resistance, if you will).  It’s why Rob Pacheco says, “to find the most efficient way to accomplish a task, give it to the laziest guy in the kitchen.”

    Conversely, when a startup grows (or starts) too big, it produces decreasingly beautiful products.  Engineers, by definition, like to engineer.  An average engineer - which most of them are, by definition of the word average - will not achieve perfection.  Since these engineers have to do something with their time, the company they work for ends up with an over-engineered product (by definition!).  It is the rare exception (i.e. Apple) that can produce many beautiful products by the labor of many engineers.

    -A Lazy Engineer

     

    tags:  engineering  fail 

    Comments
  7. Flash Now!

    In development of a new, greenfield application I had flash messages popping up twice: once for the current page, and then again on the next page.  It turns out I was using flash[]= and then rendering within the same action.  As flash[]= is designed to carry over to the next action (i.e. after you redirect, a new action is performed) it was showing up again.  The solution: flash.now[]=.  This hash is cleared after the current action.  The following code illustrates when to use each:

    def create_application
      #do work
      if it_worked?
        flash[:notice] = "Great success!"
        redirect_to @cash
      else
        flash.now[:error] = "Let's try that again"
        render :action => "new"
      end
    end
    

    The flash[:notice] must be carried over to the action that handles the @cash path (following to the redirect), whereas the flash.now[:error] will be shown for the current action (even though it renders a different view) and should not be carried over to the next action.

    It seems somewhat strange to me that I’m just discovering this now.  I suppose that as I learn more about Rails and web applications in general, I adjust my techniques and start experimenting with new ones (that aren’t always better).  The fact that flash[]= carries over to the next action and flash.now[]= doesn’t has only come into play now that I’m using flash as more of a central messaging system than just the standard notices from scaffolds.

     

    tags:  ruby  rails  fail 

    Comments
  8. Cryptic ActiveRecord::Observer error

    Why do programming languages supply such awful and cryptic error messages?  From what I’ve read of Object-C 2.0, Apple is working to change all this.  But until I start coding in Obj-C 2.0 or Ruby gets in line, I’ll have to continue following my gut before following the error message…

    I added an observer to my environment.rb file like follows:

    config.active_record.observers = :listing

    Since I created the observer with the rails generator, I should have written:

    config.active_record.observers = :listing_observer

    Shouldn’t be a big deal, except I continued to code a few new things before testing it all out.  When I saw the following error message, it wasn’t immediately clear that I had written :listing where rails wanted :listing_observer:

    /.../lib/active_record/base.rb:1959:in `method_missing_without_paginate': undefined method `instance' for #<Class:0x103568ca0> (NoMethodError)

     

    tags:  ruby  rails  error  fail 

    Comments
  9. blog comments powered by Disqus