<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nobody Listens Anyway</title>
	<atom:link href="http://www.justinball.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.justinball.com</link>
	<description>Life is an optimization issue</description>
	<lastBuildDate>Thu, 12 Jan 2012 22:25:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>XMLHttpRequest status 0 and responseText is empty</title>
		<link>http://www.justinball.com/2012/01/12/xmlhttprequest-status-0-and-responsetext-is-empty/</link>
		<comments>http://www.justinball.com/2012/01/12/xmlhttprequest-status-0-and-responsetext-is-empty/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 22:25:07 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Funny]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1676</guid>
		<description><![CDATA[I ran across a problem in the javascript for the OER Glue mashup process today that surprised me. We're using backbone.js and so I had constructed a login form via one of the views. When the form was submitted I would create a session object and then attempt to save that to the server. The [...]]]></description>
			<content:encoded><![CDATA[<p>I ran across a problem in the javascript for the <a href="http://www.oerglue.com">OER Glue</a> mashup process today that surprised me. We're using backbone.js and so I had constructed a login form via one of the views. When the form was submitted I would create a session object and then attempt to save that to the server. The problem was that the ajax request would immediately fail before the server returned anything and the XMLHttpRequest status was 0 and the responseText was empty. It took me way to long to realize that the submit button was cause the form to attempt to submit and since the form lacked an action attribute it couldn't submit anywhere and the request would fail. Changing<br />
<input type="submit" /> to <button> solves the problem. However, doing so also means the user can't hit enter to submit the form. Instead leave the<br />
<input type="submit" /> in place and return false from the method that handles the request or call event.preventDefault().</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2012/01/12/xmlhttprequest-status-0-and-responsetext-is-empty/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Require.js, Backbone.js and Almond.js Example Application</title>
		<link>http://www.justinball.com/2011/12/22/require-js-backbone-js-and-almond-js-example-application/</link>
		<comments>http://www.justinball.com/2011/12/22/require-js-backbone-js-and-almond-js-example-application/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 23:44:36 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[require.js]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1673</guid>
		<description><![CDATA[We refactored OERGlue to use backbone.js. That makes our life a lot simpler. Along the way we discovered require.js and I entered nerdvana. The documentation for require.js and backbone.js are both good and it doesn't take to long to read through the code. However, putting them together, getting the development environment right and then deploying [...]]]></description>
			<content:encoded><![CDATA[<p>We refactored <a href="http://www.oerglue.com" title="OER Glue">OERGlue</a> to use <a href="http://documentcloud.github.com/backbone/" title="Backbone.js">backbone.js</a>. That makes our life a lot simpler. Along the way we discovered <a href="http://requirejs.org/" title="Require.js">require.js</a> and I entered nerdvana. The documentation for require.js and backbone.js are both good and it doesn't take to long to read through the code. However, putting them together, getting the development environment right and then deploying can be a bit of a challenge. </p>
<p><a href="http://tagneto.blogspot.com/" title="James Burke">James Burke</a> was kind enough to guide me through getting my project setup. In hopes that my experience will help someone else get started I've put together an example application that contains the basics that you need to get started:</p>
<p><a href="https://github.com/jbasdf/requirejs-backbone-example" title="Require.js, jQuery, Backbone.js example application">https://github.com/jbasdf/requirejs-backbone-example</a></p>
<p>Merry Christmas!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/12/22/require-js-backbone-js-and-almond-js-example-application/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Script Your Development Environment Setup on Your New Mac</title>
		<link>http://www.justinball.com/2011/12/03/script-your-development-environment-setup-on-your-new-mac/</link>
		<comments>http://www.justinball.com/2011/12/03/script-your-development-environment-setup-on-your-new-mac/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 22:55:51 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1669</guid>
		<description><![CDATA[Just in time for Christmas. Every developer who's been good this year is hoping for a new MacBook under the tree. (Actually your better off waiting since Apple is likely to release new machines in 4 or 5 months). Anyway, if you need to setup a development environment in a hurry here are some scripts [...]]]></description>
			<content:encoded><![CDATA[<p>Just in time for Christmas. Every developer who's been good this year is hoping for a new MacBook under the tree. (Actually your better off waiting since Apple is likely to release new machines in 4 or 5 months). Anyway, if you need to setup a development environment in a hurry here are some scripts that will make your life a whole lot sweeter:</p>
<p><strong>Thoughtbot</strong> provides instructions and a laptop setup script. This one installs a whole lot of stuff but it's pretty close to my typical install:<br />
<a href="http://robots.thoughtbot.com/post/8700977975/2011-rubyists-guide-to-a-mac-os-x-development" title="Thoughtbot Laptop Setup Script">http://robots.thoughtbot.com/post/8700977975/2011-rubyists-guide-to-a-mac-os-x-development</a></p>
<p><strong>Pivotal Labs</strong> provides something similar. <a href="https://github.com/pivotal/pivotal_workstation/tree/master/recipes" title="Pivotal Labs chef recipes for laptop setup.">You get all this stuff</a>. Again this is close to my setup and Pivotal Labs does some pretty intense testing so I'll probably give this one a go the next time I need to install<br />
<a href="https://github.com/pivotal/pivotal_workstation" title="Pivotal Labs laptop setup.">https://github.com/pivotal/pivotal_workstation</a></p>
<p><strong>Lunar Station</strong> appears to take your machine from nothing to everything via chef scripts. (I like the idea of using chef). It does install Chrome and Skype and appears to use homebrew for a lot of the work:<br />
<a href="https://github.com/LunarLogicPolska/lunar-station" title="Lunar Station setup script">https://github.com/LunarLogicPolska/lunar-station</a></p>
<p><strong>Bitnami</strong> provides an installer, a virtual machine and an image you can run in the cloud. Looks super simple and having images you can just turn on in the cloud might be fun:<br />
<a href="http://bitnami.org/stack/rubystack" title="Bitnami Ruby stack">http://bitnami.org/stack/rubystack</a></p>
<p>If you are a fan of rbenv then <strong>Cinderella</strong> might help you get setup.<br />
<a href="http://www.atmos.org/cinderella/" title="Cinderella setup script">http://www.atmos.org/cinderella/</a></p>
<p>If you want to test different IE versions MS provides virtual machines. This script helps set it all up using Virtual box:<br />
<a href="https://github.com/xdissent/ievms" title="IE testing script for the Mac">https://github.com/xdissent/ievms</a></p>
<p>I've not had a lot of time to dig into <strong>babushka</strong>, but it looks sweet and claims to be your test-driven sysadmin. I'm guessing there are scripts to setup everything you need for your development environment but I've not found them yet.<br />
<a href="https://github.com/benhoskings/babushka">https://github.com/benhoskings/babushka</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/12/03/script-your-development-environment-setup-on-your-new-mac/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Customizing Views for a Multi-Tenant Application Using Ruby on Rails Custom Resolvers</title>
		<link>http://www.justinball.com/2011/09/27/customizing-views-for-a-multi-tenant-application-using-ruby-on-rails-custom-resolvers/</link>
		<comments>http://www.justinball.com/2011/09/27/customizing-views-for-a-multi-tenant-application-using-ruby-on-rails-custom-resolvers/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 15:31:57 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Ruby On Rails]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1650</guid>
		<description><![CDATA[Like so many other internet startups, OER Glue is a multi-tenant application. The process of hosting many of clients using a single piece of software presents a number of challenges and one of the largest has been customizing the look for each customer. I've tried solving this a number of different ways over the years [...]]]></description>
			<content:encoded><![CDATA[<p>Like so many other internet startups, <a href="http://www.oerglue.com" title="OER Glue">OER Glue</a> is a multi-tenant application. The process of hosting many of clients using a single piece of software presents a number of challenges and one of the largest has been customizing the look for each customer. I've tried solving this a number of different ways over the years including writing a gem called <a href="https://github.com/jbasdf/disguise" title="Disguise Gem">disguise</a> that let's you customize look of your Rails site in a way similar to the method WordPress uses. That gem will customize the views based on the domain, but it's not especially efficient.</p>
<p>With <a href="http://www.oerglue.com" title="OER Glue">OER Glue</a> we needed something that didn't effect performance and that didn't require a new deploy every time we need to customize a view for a customer. If you've run into this problem then you've problem also prayed to the omniscient Google and found this <a href="http://blog.plataformatec.com.br/2011/04/default-views-in-rails-3-0-with-custom-resolvers/" title="Custom Resolvers in Rails 3.1">great article by Jose Valim on creating custom resolvers</a>. About half way through I got really excited and decided to check out his book <a href="http://plataformatec.com.br/crafting-rails-applications/" title="Crafting Rails Applications">Crafting Rails Applications</a>. Then I got really, really excited when I realized I had already bought it.</p>
<p>It turns out Chapter 3 from the book describes creating a custom template resolver for Ruby on Rails that pulls templates from the database. It also caches them so you aren't constantly hitting the database which would result in a nasty performance hit. If you want to understand how the resolver works then it really is worth buying the book. The solution Jose presents solved 90% of my problem.</p>
<p>However, I was still left with one really big issue - how do I get information from the controller into the custom view resolver? Specifically, I needed to pass information about the current domain into the resolver so that I could scope the views to the current account.<br />
Here's the specific snippet responsible for retrieving template from the database:</p>
<pre class="ruby">&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> find_templates<span style="color:#006600; font-weight:bold;">&#40;</span>name, prefix, partial, details<span style="color:#006600; font-weight:bold;">&#41;</span>
      conditions = <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:path</span>    =&gt; normalize_path<span style="color:#006600; font-weight:bold;">&#40;</span>name, prefix, partial<span style="color:#006600; font-weight:bold;">&#41;</span>,
        <span style="color:#ff3333; font-weight:bold;">:locale</span>  =&gt; normalize_array<span style="color:#006600; font-weight:bold;">&#40;</span>details<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:locale</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>,
        <span style="color:#ff3333; font-weight:bold;">:format</span>  =&gt; normalize_array<span style="color:#006600; font-weight:bold;">&#40;</span>details<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:formats</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>,
        <span style="color:#ff3333; font-weight:bold;">:handler</span> =&gt; normalize_array<span style="color:#006600; font-weight:bold;">&#40;</span>details<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:handlers</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>,
        <span style="color:#ff3333; font-weight:bold;">:partial</span> =&gt; partial || <span style="color:#0000FF; font-weight:bold;">false</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#0066ff; font-weight:bold;">@account</span>.<span style="color:#9900CC;">custom_views</span>.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span>conditions<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span> <span style="color:#9966CC; font-weight:bold;">do</span> |record|
        initialize_template<span style="color:#006600; font-weight:bold;">&#40;</span>record<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>The problem is that in the book the resolver is a singleton and so there is no opportunity to pass in the an account and setup an @account value since the resolver is setup in the application controller like this:</p>
<pre class="ruby">&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController &lt; <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
  prepend_view_path <span style="color:#6666ff; font-weight:bold;">SqlTemplate::Resolver</span>.<span style="color:#9900CC;">instance</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>At first I decided to just use a global on the current thread:</p>
<pre class="ruby">&nbsp;
<span style="color:#CC00FF; font-weight:bold;">Thread</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:account</span><span style="color:#006600; font-weight:bold;">&#93;</span> = current_account
&nbsp;</pre>
<p>Then inside the resolver I could recover the account from the global:</p>
<pre class="ruby">&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> find_templates<span style="color:#006600; font-weight:bold;">&#40;</span>name, prefix, partial, details<span style="color:#006600; font-weight:bold;">&#41;</span>
      conditions = <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:path</span>    =&gt; normalize_path<span style="color:#006600; font-weight:bold;">&#40;</span>name, prefix, partial<span style="color:#006600; font-weight:bold;">&#41;</span>,
        <span style="color:#ff3333; font-weight:bold;">:locale</span>  =&gt; normalize_array<span style="color:#006600; font-weight:bold;">&#40;</span>details<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:locale</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>,
        <span style="color:#ff3333; font-weight:bold;">:format</span>  =&gt; normalize_array<span style="color:#006600; font-weight:bold;">&#40;</span>details<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:formats</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>,
        <span style="color:#ff3333; font-weight:bold;">:handler</span> =&gt; normalize_array<span style="color:#006600; font-weight:bold;">&#40;</span>details<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:handlers</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>,
        <span style="color:#ff3333; font-weight:bold;">:partial</span> =&gt; partial || <span style="color:#0000FF; font-weight:bold;">false</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC00FF; font-weight:bold;">Thread</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:account</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">custom_views</span>.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span>conditions<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span> <span style="color:#9966CC; font-weight:bold;">do</span> |record|
        initialize_template<span style="color:#006600; font-weight:bold;">&#40;</span>record<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>That works but setting a global on the current thread felt like a big hack. (<a href="http://coderrr.wordpress.com/2008/04/10/lets-stop-polluting-the-threadcurrent-hash/" title="Stop polluting the Thread.current hash">Here's a good article on Thread.current</a>  ) Lucky for me Jose was willing to spend a little time working with me and the resulting code works without globals. Instead of passing a global around we removed the Singleton code from the resolver and create an instance of the resolver per each account:</p>
<pre class="ruby">&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController &lt; <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
  before_filter <span style="color:#ff3333; font-weight:bold;">:set_resolver</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> current_account
    <span style="color:#0066ff; font-weight:bold;">@current_account</span> ||= Account.<span style="color:#9900CC;">find_by_domain</span><span style="color:#006600; font-weight:bold;">&#40;</span>request.<span style="color:#9900CC;">host</span><span style="color:#006600; font-weight:bold;">&#41;</span> || Account.<span style="color:#9900CC;">find_by_code</span><span style="color:#006600; font-weight:bold;">&#40;</span>request.<span style="color:#9900CC;">subdomains</span>.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#41;</span> || Account.<span style="color:#9900CC;">first</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  @@account_resolver = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> account_resolver_for<span style="color:#006600; font-weight:bold;">&#40;</span>account<span style="color:#006600; font-weight:bold;">&#41;</span>
    @@account_resolver<span style="color:#006600; font-weight:bold;">&#91;</span>account.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#93;</span> ||= <span style="color:#6666ff; font-weight:bold;">CustomView::Resolver</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>account<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> set_resolver
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">unless</span> current_account
    resolver = account_resolver_for<span style="color:#006600; font-weight:bold;">&#40;</span>current_account<span style="color:#006600; font-weight:bold;">&#41;</span>
    resolver.<span style="color:#9900CC;">update_account</span><span style="color:#006600; font-weight:bold;">&#40;</span>current_account<span style="color:#006600; font-weight:bold;">&#41;</span>
    prepend_view_path resolver
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>In the resolver we take the account as a parameter. The trick is that the account also has a counter called 'custom_view_cache_count' that increments anytime a view is changed thus allowing us to expire the cache across all instances and servers. Since I have to recover the account model from the database on each request anyway this doesn't require any more database hits than I was making before adding this solution:</p>
<pre class="ruby">&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> Resolver &lt; <span style="color:#6666ff; font-weight:bold;">ActionView::Resolver</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>account<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@account</span> = account
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Check if the custom_view_cache_count is still the same, if not clear the cache</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> update_account<span style="color:#006600; font-weight:bold;">&#40;</span>updated_account<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">clear_cache</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@account</span>.<span style="color:#9900CC;">custom_view_cache_count</span> == updated_account.<span style="color:#9900CC;">custom_view_cache_count</span>
      <span style="color:#0066ff; font-weight:bold;">@account</span> = updated_account
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>This has a couple of benefits. The biggest is that you no longer have to pass around a global, but another is that the cache is specific to each account so you don't end up expire the cache for all accounts unnecessarily. </p>
<p>Big thanks to Jose for helping me figure this one out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/09/27/customizing-views-for-a-multi-tenant-application-using-ruby-on-rails-custom-resolvers/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Backbone.js &#8211; Clean up your views</title>
		<link>http://www.justinball.com/2011/09/14/backbone-js-clean-up-your-views/</link>
		<comments>http://www.justinball.com/2011/09/14/backbone-js-clean-up-your-views/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 03:56:29 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1647</guid>
		<description><![CDATA[I've been integrating backbone.js into OER Glue. After years of writing all kinds of spaghetti javascript code to manage client side ajax backbone.js is like manna from heaven. If you're new to backbone.js and you want to use it with Ruby on Rails James Yu has a couple of great posts to get you going. [...]]]></description>
			<content:encoded><![CDATA[<p>I've been integrating <a href="http://documentcloud.github.com/backbone/">backbone.js</a> into <a href="http://www.oerglue.com">OER Glue</a>. After years of writing all kinds of spaghetti javascript code to manage client side ajax backbone.js is like manna from heaven. If you're new to backbone.js and you want to use it with Ruby on Rails <a href="http://www.jamesyu.org/2011/01/27/cloudedit-a-backbone-js-tutorial-by-example/">James Yu has a couple of great posts to get you going</a>. The tutorial is for an older version so substitute router for controller and you'll be most of the way to the latest version.</p>
<p>I followed the example and wrote some admin interface code. When I was writing the code I wondered about doing this over and over again:</p>
<pre class="javascript">&nbsp;
<span style="color: #003366; font-weight: bold;">new</span> App.<span style="color: #006600;">Views</span>.<span style="color: #006600;">Edit</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span> model: doc <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>In the example that code greats a new view anytime you hit the new or edit action. The edit view code binds to the submit form event so that whenever the form is submitted it calls the save action in the edit view:</p>
<pre class="javascript">&nbsp;
    events: <span style="color: #66cc66;">&#123;</span>
        <span style="color: #3366CC;">&quot;submit form&quot;</span>: <span style="color: #3366CC;">&quot;save&quot;</span>
    <span style="color: #66cc66;">&#125;</span>,
&nbsp;</pre>
<p>That makes sense, but the one thing the tutorial doesn't teach you to do is clean up the views. In fact I don't think it has to because it just creates a new element and adds it to the DOM with each call to new. However, in my case I use the 'el' attribute to attach my view to the DOM like this:</p>
<pre class="javascript">&nbsp;
App.<span style="color: #006600;">Views</span>.<span style="color: #006600;">Edit</span> = Backbone.<span style="color: #006600;">View</span>.<span style="color: #006600;">extend</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span>
  el: <span style="color: #3366CC;">'#new-custom-view-form'</span>,
  ...
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>In that case if you keep creating new views with new App.Views.Edit you'll also keep binding the submit form event to the same submit button. The result is that if you press the 'Save' button on the form it will call the event for every view that you've created. That can be very bad since you will end saving models to the server that you didn't intend. </p>
<p>My solution was to create the view once in the router's initialize method and then I set the model in the view whenever new or edit is called. That works great in my case. The <a href="http://workshops.thoughtbot.com/backbone-js-on-rails">Thoughtbot guys are writing a backbone.js book</a> that explains the creating a 'Swappable' router that calls a 'leave' method whenever the same view is instantiated again. The leave method is responsible for unbinding any events and should remove the element from the DOM. The book isn't done, but what they've put together looks good. I think $49 is pretty steep for an ebook when Pragmatic Programmers is charging more like $20-$30, but I paid the money so it doesn't really matter what I think. </p>
<p>On a side note the James Yu's tutoral also has this line:</p>
<pre class="javascript">&nbsp;
Backbone.<span style="color: #006600;">history</span>.<span style="color: #006600;">saveLocation</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'documents/'</span> + model.<span style="color: #006600;">id</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>That won't work in the latest version of backbone.js. Instead do:</p>
<pre class="javascript">&nbsp;
Backbone.<span style="color: #006600;">history</span>.<span style="color: #000066;">navigate</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'documents/'</span> + model.<span style="color: #006600;">id</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/09/14/backbone-js-clean-up-your-views/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pushing my luck with jQuery. Scope matters.</title>
		<link>http://www.justinball.com/2011/08/26/pushing-my-luck-with-jquery-scope-matters/</link>
		<comments>http://www.justinball.com/2011/08/26/pushing-my-luck-with-jquery-scope-matters/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 22:22:17 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1644</guid>
		<description><![CDATA[OER Glue makes heavy use of jQuery. We're currently working on a proxy version of the technology that won't require installing a browser plugin. It's pretty cool.
One of the biggest challenges for us has been ensuring consistent look, feel and operation of our technology across any possible website on the Internet. That's not a small [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.oerglue.com" title="OER Glue" target="_blank">OER Glue</a> makes heavy use of jQuery. We're currently working on a proxy version of the technology that won't require installing a browser plugin. It's pretty cool.</p>
<p>One of the biggest challenges for us has been ensuring consistent look, feel and operation of our technology across any possible website on the Internet. That's not a small challenge. A key to making everything work is to not stomp on anything the web page is already doing. We use jQuery and so do a lot of page on the Web. That means we have to carefully load the version that we use (since lots of sites use old versions) and then put everything back. A call to noConflict make this possible:</p>
<pre class="javascript">&nbsp;
oerglue_jquery = window.<span style="color: #006600;">jQuery</span>.<span style="color: #006600;">noConflict</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;</pre>
<p>That magic doesn't come without costs. We don't use any jQuery plugins because it's not likely they will work with our scoped version of jQuery. I also ran into an interested problem with class selectors. For some reason jQuery class selectors for the oerglue_jquery object return an empty array on the MIT OCW site. However, for some reason they work fine on other sites. I found the problem a bit baffling and honestly I don't know the cause. I'm hoping someone smarter than me can expose my jQuery ignorance.</p>
<p>In the mean time I have a cool solution that comes with a performance boost. In the MIT OCW case selectors by id return a value. That means I can first get the OER Glue toolbar container by its id. I then pass that as the scope to the jQuery selector that uses classes and like magic everything works. The side benefit is that adding scope makes your selectors faster since jQuery won't have to traverse the entire DOM.</p>
<p>That brings up a good point. Always scope your jQuery selectors and use ids where possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/08/26/pushing-my-luck-with-jquery-scope-matters/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Loving Goliath. Watch Out for Stones</title>
		<link>http://www.justinball.com/2011/07/19/loving-goliath-watch-out-for-stones/</link>
		<comments>http://www.justinball.com/2011/07/19/loving-goliath-watch-out-for-stones/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 21:27:56 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[OER]]></category>
		<category><![CDATA[OER Glue]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Event Machine]]></category>
		<category><![CDATA[Goliath]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1637</guid>
		<description><![CDATA[We've been looking at proxy solutions to help us deliver OER Glue courses to learners without the requirement of installing an extension. There are an insane number of proxy solutions out there that do all kinds of really incredible things. 
For the delivery of courses and modification of pages we really only need something that [...]]]></description>
			<content:encoded><![CDATA[<p>We've been looking at proxy solutions to help us deliver <a href="http://www.oerglue.com/courses">OER Glue courses</a> to learners without the requirement of installing an extension. There are an insane number of proxy solutions out there that do all kinds of really incredible things. </p>
<p>For the delivery of courses and modification of pages we really only need something that will grab a page on a user's behalf, add some scripts and then pass it along.</p>
<p>I can across <a href="https://github.com/igrigorik/em-proxy">em-proxy</a> which I really liked since it was written in Ruby and I really love Ruby. <a href="http://www.igvita.com/">IIya Grigorik</a> was kind enough to answer a bunch of my noob questions and finally suggested that I look at <a href="http://postrank-labs.github.com/goliath/">Goliath</a>.  </p>
<p>I keep seeing that Goliath is the <a href="http://nodejs.org/">node.js</a> of Ruby. Given the popularity of node.js that's an easy way to grasp the architecture. Both use an <a href="http://en.wikipedia.org/wiki/Event_loop">"event loop" architecture</a>. I think that the primary difference is the philosophy. node.js is close to the metal while <a href="http://www.igvita.com/2011/03/08/goliath-non-blocking-ruby-19-web-server/">Golaith abstracts away the callbacks to make writing code as simple as possible an feature that IIya and the team at Post Rank felt was important for maintainability</a>.</p>
<p>That's not to say node.js is not as good. I really love node.js and we had started investigating <a href="node-http-proxy">node-http-proxy</a> from the <a href="http://www.nodejitsu.com/">nodejitsu</a> guys. I like the code base but it wasn't quite the right fit. For performance (low memory usage) <a href="https://github.com/nodejitsu/node-http-proxy/issues/58">node-http-proxy doesn't buffer what's it's proxying and so you don't have a chance to modify the DOM</a>. It looks like there is some effort going into making that possible but after reading through the issues I've come to the conclusion that what we need is something a little more than just a proxy.</p>
<p>Enter Goliath.</p>
<p>Here's a really simple example of what we will end up doing:</p>
<pre lang="ruby>
require 'rubygems'
require 'goliath'
require 'em-synchrony'
require 'em-synchrony/em-http'

class OerglueProxy < Goliath::API
  use Goliath::Rack::Params

  def response(env)
    req = EM::HttpRequest.new("http://www.google.com/").get
    resp = req.response

    [200, {'X-Goliath' => 'Proxy'}, resp]
  end
end
</pre>
<p>In just a few lines of code we're able to retrieve a page and return the results. All the async code that EventMachine provides and that gives us great performance is hidden away. We can focus on our logic. We can also utilize our team's Ruby development strength. I like that.</p>
<p>I did run into issues getting the right version of the gems I needed. Specifically, I kept getting this error:</p>
<pre>
`class_eval': undefined method `get' for module `EventMachine::HTTPMethods' (NameError)
</pre>
<p>I found <a href="https://github.com/igrigorik/em-synchrony/issues/29">a solution in this thread</a>, but it didn't quite work for me.</p>
<p>Luckily bundler makes it easy to get the exact version of the gem you need and with a little playing around here's what I came up with:</p>
<pre>
source "http://rubygems.org"

gem 'goliath', '0.9.1'
gem 'eventmachine', '1.0.0.beta.3'
gem 'em-http-request', '1.0.0.beta.4'
gem "em-synchrony", '0.3.0.beta.1'

group :test, :development do
  gem "rspec"
end
</pre>
<p>Goliath has been in use by Post Rank for over a year and serves ~500 requests per second. I'm looking forward to seeing how it works to serve up courses on <a href="http://www.oerglue.com">OER Glue</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/07/19/loving-goliath-watch-out-for-stones/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ruby 1.9.2, rvm and a Nasty Error When Installing RubyGems: couldn&#8217;t parse YAML at line 2 column 10 (Psych::SyntaxError)</title>
		<link>http://www.justinball.com/2011/07/18/ruby-1-9-2-rvm-and-a-nasty-error-when-installing-rubygems-couldnt-parse-yaml-at-line-2-column-10-psychsyntaxerror/</link>
		<comments>http://www.justinball.com/2011/07/18/ruby-1-9-2-rvm-and-a-nasty-error-when-installing-rubygems-couldnt-parse-yaml-at-line-2-column-10-psychsyntaxerror/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 05:01:19 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[psych]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1632</guid>
		<description><![CDATA[It's 'funny' how seemingly simple things take you down nasty paths. I was hoping to spend a few minutes playing with Goliath. That led me to installing ruby 1.9.2 using rvm which spit out this error:

Removing old Rubygems files...
Installing rubygems dedicated to ruby-1.9.2-p290...
Installing rubygems for /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/bin/ruby
ERROR: Error running 'GEM_PATH="/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290@global:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290@global" GEM_HOME="/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290" "/Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/bin/ruby" "/Users/jbasdf/.rvm/src/rubygems-1.6.2/setup.rb"', please read /Users/jbasdf/.rvm/log/ruby-1.9.2-p290/rubygems.install.log
WARN: [...]]]></description>
			<content:encoded><![CDATA[<p>It's 'funny' how seemingly simple things take you down nasty paths. I was hoping to spend a few minutes playing with <a href="http://www.igvita.com/2011/03/08/goliath-non-blocking-ruby-19-web-server/">Goliath</a>. That led me to installing ruby 1.9.2 using rvm which spit out this error:</p>
<pre>
Removing old Rubygems files...
Installing rubygems dedicated to ruby-1.9.2-p290...
Installing rubygems for /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/bin/ruby
ERROR: Error running 'GEM_PATH="/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290@global:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290@global" GEM_HOME="/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290" "/Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/bin/ruby" "/Users/jbasdf/.rvm/src/rubygems-1.6.2/setup.rb"', please read /Users/jbasdf/.rvm/log/ruby-1.9.2-p290/rubygems.install.log
WARN: Installation of rubygems did not complete successfully.
</pre>
<p>That's not especiallyl pretty but it did point me to a log file which contained this:</p>
<pre>
/Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse': couldn't parse YAML at line 2 column 10 (Psych::SyntaxError)
        from /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse_stream'
        from /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:119:in `parse'
[2011-07-18 18:29:21] GEM_PATH="/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290@global:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290:/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290@global" GEM_HOME="/Users/jbasdf/.rvm/gems/ruby-1.9.2-p290" "/Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/bin/ruby" "/Users/jbasdf/.rvm/src/rubygems-1.6.2/setup.rb"
/Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse': couldn't parse YAML at line 2 column 10 (Psych::SyntaxError)
        from /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse_stream'
        from /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:119:in `parse'
        from /Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:106:in `load'
        from /Users/jbasdf/.rvm/src/rubygems-1.6.2/lib/rubygems/config_file.rb:235:in `load_file'
        from /Users/jbasdf/.rvm/src/rubygems-1.6.2/lib/rubygems/config_file.rb:179:in `initialize'
        from /Users/jbasdf/.rvm/src/rubygems-1.6.2/lib/rubygems/gem_runner.rb:76:in `new'
        from /Users/jbasdf/.rvm/src/rubygems-1.6.2/lib/rubygems/gem_runner.rb:76:in `do_configuration'
        from /Users/jbasdf/.rvm/src/rubygems-1.6.2/lib/rubygems/gem_runner.rb:49:in `run'
        from /Users/jbasdf/.rvm/src/rubygems-1.6.2/setup.rb:35:in `<main>'
</pre>
<p>Again not especially helpful. However, ruby and all it's lovely gems are open source so I dropped a 'puts' statement into 'config_file.rb' (/Users/jbasdf/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/rubygems/config_file.rb) and found the culprit - a very ugly .gemrc file in my home directory that I probably put there years ago. It looks like this:</p>
<pre>
echo -e '---
:benchmark: false
gem: --no-ri --no-rdoc
:update_sources: true
:bulk_threshold: 1000
:verbose: true
:backtrace: false' > ~/.gemrc
</pre>
<p>psych - the yaml processor for ruby 1.9.2 - didn't like that ugly yaml at all. I removed my .gemrc file (I don't need anything custom) and everything started to work.</p>
<p>If you run into this problem the paths will be specific to your machine but hopefully the ideas help.</p>
<p>A couple of takeaways:</p>
<ol>
<li>You can tweak anything in Ruby. Don't be afraid to mess around with anything to find your problem.</li>
<li>I knew #1, but for some reason I always try everything else before going for #1. I gotta just go for #1 to start with and save myself the time.</li>
<li>I love Ruby</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/07/18/ruby-1-9-2-rvm-and-a-nasty-error-when-installing-rubygems-couldnt-parse-yaml-at-line-2-column-10-psychsyntaxerror/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cycling in Teton Valley (Driggs, ID)</title>
		<link>http://www.justinball.com/2011/07/10/cycling-in-teton-valley-driggs-id/</link>
		<comments>http://www.justinball.com/2011/07/10/cycling-in-teton-valley-driggs-id/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 03:39:05 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Cycling]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1615</guid>
		<description><![CDATA[ Just spent the week with my family in Teton Valley and Grand Teton National Park. After four days of kids, mosquitoes and me biking every day my wife is not going to divorce me so it's been a great vacation. Of course as I type this Callie is giving me grief that of all [...]]]></description>
			<content:encoded><![CDATA[<p> Just spent the week with my family in Teton Valley and Grand Teton National Park. After four days of kids, mosquitoes and me biking every day my wife is not going to divorce me so it's been a great vacation. Of course as I type this Callie is giving me grief that of all the things I write about it's the biking so stay tuned on the divorce front.</p>
<p>Actually, Callie is a great wife and very patient to let me get up, abandon her to get the kids ready and ride for a couple of hours each morning and once in the middle of the day. I'm not winning any father of the year awards but she might deserve sainthood. I owe her big time and so once again I offer to purchase her any bike she likes. (and we're going on vacation again this next week with her family and I'm planning on taking the bikes so I need points).</p>
<p>It's amazing how hard it is to find a place to ride. I keep thinking that the Internet is an omnipotent source of all truth and knowledge, but there's not much online about riding in Teton Valley. I knew there was a bike path since I'd seen it before and my dad was a part of that project, but other than that it's hard to tune into the local biking scene unless you are a local. (It's the same everywhere I go). I finally found some maps hidden on <a href="http://tvtap.org/">Teton Valley Trails and Pathways</a>. They're stowed away under <a href="http://tvtap.org/resources/maps">resources -> maps</a>.  The one I found most useful is the <a href="http://tvtap.org/images/stories/docs/map-tvtap-cycling.pdf">TVTAP Cycling Map</a> which listed a couple of rides that looked like they made sense.. </p>
<p><a href="http://www.vrbo.com/331221">We stayed at a great cabin in the middle of the valley just a few miles north of Victor</a>. Since it wasn't far from the bike path that goes from Victor to Driggs I was able to utilize that path the first day and do "The Loop" -  a 25 mile loop around the main part of the valley.  I normally avoid bike paths when riding at higher speeds since slamming into a pedestrian makes them really mad and there's really not much glory in passing a 5 year old on his BMX. However, in Teton Valley early in the morning the bike path is relatively vacant, and you want to avoid the section of highway it parallels unless you have a lot of life insurance. Between the tourists gawking at the scenery, the locals treating it like the autobahn and the fact there is no shoulder your likely hood of early death.</p>
<p>This year the water is high all over the inter-mountain west. We've had plenty of flooding in Cache Valley and Teton Valley has seen similar issues. The entire valley floor is pretty much a giant swamp that collects the run off from the surrounding hills. I was glad for my cross bike on day one while doing the loop since the bike path had become a channel for one of the local creeks. The road across the valley from east to west had low traffic and was fast. I did have to stop to take a picture of a bald eagle: <a href="http://www.justinball.com/wp-content/uploads/2011/07/IMG_0609.jpg" ><img src="http://www.justinball.com/wp-content/uploads/photojar/cache/IMG_0609-800x1000-0-img1620.jpg" alt="" title="Bald Eagle" width="746" height="1000" class="alignnone size-medium wp-image-1620" /></a>. The <a href="http://tvtap.org/images/stories/docs/map-tvtap-cycling.pdf">TVTAP cycling map</a> mentions that the west side of the loop has a 2 mile section of gravel road that's not a big deal. I'm sure if you don't love your road bike you can ride it just fine, but I'm pretty fond of my carbon wheels and the paint on my road bike so again the cross bike was a great choice for "The Loop".  I cut the ride a bit short and came back across on North Cedron road which is the road where the cabin was. It's downhill from the main road so was able to hit it going 24 plus MPH which was fun until I hit a section of the road where for some reason they decided to dump the remains of a stone quarry. I nearly wiped out when the gravel turned to 3-4" rocks. Callie doesn't like it when I go to the hospital so I dropped my pace and did some swearing. The next section of road was under water, but being a man and all I couldn't let that stop me. I was actually surprised when it didn't and saddened that no one was around to see it. The creek there had cut a channel across the road that was a foot deep which buried the bottom half of my bike in liquid. I'm guessing that's why my power meter doesn't work anymore.</p>
<p>I slept in the next day and so decided I would just do a quick up and down the bike path. It ended up being about 20 miles and I totally left several bmx riding 5 year olds and a couple of old people in the dust. The bike path trip was actually to scout out places to park in Driggs so I could ride Ski Hill road. It felt pretty wussy to drive 8 miles so I could ride my bike, but surprisingly the point of a family trip isn't to avoid the family so I had to keep my rides short. I also checked out the local bike shop <a href="http://www.peakedsports.com/Home.html">Peaked Sports</a> - sort of anyway. I rode by. I have a history of racking up grounds for divorce credit card bills at bike shops so I thought it best that I look from a distance. They rent bikes so if you don't bring your own you can still ride. Personally I prefer to bring my own stuff. It feels weird to play with other people's equipment.</p>
<p>I saved Ski Hill road up to Grand Targee for the last day. After that ride I'm totally ready to buy one of the foreclosed cabins and spend the rest of my days just riding up and down the mountain. This is what it looks like:<br />
<a href="http://www.justinball.com/wp-content/uploads/2011/07/IMG_0614.jpg" ><img src="http://www.justinball.com/wp-content/uploads/photojar/cache/IMG_0614-800x1000-0-img1621.jpg" alt="" title="Ski Hill Road to Grand Targee" width="800" height="597" class="alignnone size-medium wp-image-1621" /></a>.<br />
If you are in town for one day do this ride. The pavement is smooth. The road ends at a ski resort so there's not a lot of traffic. The views are spectacular. I get the impression that this is the ride the locals do since I saw quite a few other bikers. I also saw a group of 3 skateboarders coming down the road. I think they were on a suicide mission.</p>
<p>There are a few other rides I want to do but didn't have time. There's a bike path from Tetonia to St Anthony that follows the old rail bed. My dad also did the engineering for that trail and has ridden it on a motorcycle and said its an amazing ride. (It's closed to motors now. When my dad did it they hadn't put a deck on the old rail trestle. He said it was a rush to ride that high up across the railroad ties without any railing.) That path is gravel but flat and seems like a great candidate for a cross bike.</p>
<p>I didn't do any mountain biking since I didn't have the time or my mountain bike, but the map lists a number of local trails which look amazing. You could spend several weeks riding and not cover the same ground. Given that I'm not a pro-biker and that I'm not retiring I probably won't be taking up permanent residence in Teton Valley any time soon, but we might have to start taking a few more family vacations to the area of the next couple of years.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/07/10/cycling-in-teton-valley-driggs-id/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upgrade to MySQL 5.5.12 and now MySQL won&#8217;t start</title>
		<link>http://www.justinball.com/2011/07/05/upgrade-to-mysql-5-5-12-and-now-mysql-wont-start/</link>
		<comments>http://www.justinball.com/2011/07/05/upgrade-to-mysql-5-5-12-and-now-mysql-wont-start/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 20:51:55 +0000</pubDate>
		<dc:creator>Justin Ball</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.justinball.com/?p=1613</guid>
		<description><![CDATA[I messed up my local install of MySQL (it's a long story that involves me almost throwing a punch to my 30" monitor). I finally gave up, deleted everything MySQL related according to these notes and then I used homebrew to do a clean install.
After the install I started getting this error:

ERROR 2002 (HY000): Can't [...]]]></description>
			<content:encoded><![CDATA[<p>I messed up my local install of MySQL (it's a long story that involves me almost throwing a punch to my 30" monitor). I finally gave up, deleted everything MySQL related according to <a href="http://akrabat.com/computing/uninstalling-mysql-on-mac-os-x-leopard/">these notes</a> and then I used homebrew to do a clean install.</p>
<p>After the install I started getting this error:</p>
<pre>
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
</pre>
<p>I couldn't figure out what was going on so I checked my logs in /usr/local/var/mysql (in that directory find a file that ends in .err). Here's what I kept seeing over and over again:</p>
<pre>
110705 14:33:20 [ERROR] /usr/local/Cellar/mysql/5.5.12/bin/mysqld: unknown variable 'default-character-set=utf8'
110705 14:33:20 [ERROR] Aborting
</pre>
<p>Turns out if you upgrade MySQL you'll want to modify /etc/my.cnf. This line causes problems:</p>
<pre>
default-character-set = utf8
</pre>
<p>Remove that and you should be good. For reference here's what my '/etc/my.cnf' file looks like:</p>
<pre>
[mysqld]
max_allowed_packet=64M
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
</pre>
<p>As a side note be sure to change max_allowed_packet to something like 64M. I was trying to restore a large database and MySQL kept barfing with this error:<br />
ERROR 2006 (HY000) at line 682: MySQL server has gone away</p>
<p>Turns out the default packet size is to small to restore all but the smallest databases.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.justinball.com/2011/07/05/upgrade-to-mysql-5-5-12-and-now-mysql-wont-start/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

