<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>without_scope - Home</title>
  <id>tag:withoutscope.com,2009:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  
  <link href="http://withoutscope.com/" rel="alternate" type="text/html" />
  <updated>2009-09-20T00:07:41Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/without_scope" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2009-09-20:326</id>
    <published>2009-09-20T00:06:00Z</published>
    <updated>2009-09-20T00:07:41Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/7oYWolHx1nI/acts-_as-_revisable-1-1-1-now-with-sti-love-and-more" rel="alternate" type="text/html" />
    <title>acts_as_revisable 1.1.1 - now with STI love and more</title>
<content type="html">
            &lt;p&gt;I’ve been buried in launch prep for work and really needed a break. Not from coding, just from work. So, I went through and pulled in several changes from the friendly strangers on GitHub and corrected the issues listed in all the GitHub tickets.&lt;/p&gt;

&lt;h1&gt;Single table inheritance&lt;/h1&gt;

&lt;p&gt;acts_as_revisable was previously non-functional on STI models. Now it works nicely. I do suspect there may be a few more issues lurking with this but, in my testing I didn’t run across anything.&lt;/p&gt;

&lt;p&gt;Note: It does require explicit use of the acts_as_(revisable|revision) calls in all the subclasses.&lt;/p&gt;

&lt;p&gt;Thanks &lt;a href="http://jroller.com/dscataglini/"&gt;Diego Scataglini&lt;/a&gt; for the report.&lt;/p&gt;

&lt;h1&gt;validates_uniqueness_of&lt;/h1&gt;

&lt;p&gt;This issue was reported in detail by &lt;a href="http://chrisblunt.com/blog/2009/08/06/rails-validating-unique-attributes-with-acts_as_revisable/"&gt;Chris Blunt&lt;/a&gt;. Basically, for the revisable and revision models I use Rails’ default_scope functionality. validates_uniqueness_of ignores the default scope.&lt;/p&gt;

&lt;p&gt;acts_as_revisable now patches validates_uniqueness_of by default while allowing you to disable this functionality with a simple flag.&lt;/p&gt;

&lt;p&gt;Thanks Chris.&lt;/p&gt;

&lt;h1&gt;Miscellaneous bug fixes&lt;/h1&gt;

&lt;p&gt;There were a bunch of little bug fixes from a few users on GitHub. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;proper time zone support&lt;/li&gt;
&lt;li&gt;added and better specs describing revision number behavior&lt;/li&gt;
&lt;li&gt;corrected a bug with revision numbering&lt;/li&gt;
&lt;li&gt;support #find_revision(:last)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you &lt;a href="http://github.com/moklett"&gt;moklett&lt;/a&gt;, &lt;a href="http://github.com/martinh"&gt;martinh&lt;/a&gt; and &lt;a href="http://github.com/aguynamedryan"&gt;aguynamedryan&lt;/a&gt;.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/7oYWolHx1nI" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2009/9/20/acts-_as-_revisable-1-1-1-now-with-sti-love-and-more</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2009-07-21:320</id>
    <published>2009-07-21T02:43:00Z</published>
    <updated>2009-07-21T02:43:33Z</updated>
    <link href="http://feedproxy.google.com/~r/without_scope/~3/0FOpr-RhU0E/exploring-postgresql-8-4-recursive-queries" rel="alternate" type="text/html" />
    <title>Exploring PostgreSQL 8.4 - Recursive Queries</title>
<content type="html">
            &lt;p&gt;This topic has honestly been covered really well by the various PostgreSQL-covered bloggers. I’m simply hoping to expose my handful of friends who read this blog to some of the new beauty of 8.4.&lt;/p&gt;

&lt;p&gt;Recursive queries in PostgreSQL are part of Common Table Expressions or CTEs. They’re kinda like views defined on demand as part of a query.&lt;/p&gt;

&lt;h2&gt;Jumping right into code&lt;/h2&gt;

&lt;p&gt;I think the perfect example for recursive queries is a tree structure such as categories. So that’s what we’ll build:&lt;/p&gt;

&amp;lt;script src="http://gist.github.com/151063.js"&gt;&amp;lt;/script&gt; 

&lt;p&gt;Now, if we want to select all categories that are children of the ‘three’ category, we can with one recursive query:&lt;/p&gt;

&amp;lt;script src="http://gist.github.com/151067.js"&gt;&amp;lt;/script&gt;

&lt;p&gt;Let’s go through that line by line.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Line 1: we create a recursive CTE called all_categories&lt;/li&gt;
&lt;li&gt;Line 2: we define the first query executed which selects the initial data&lt;/li&gt;
&lt;li&gt;Line 3: for a recursive query, PostgreSQL requires a UNION in the CTE. This UNIONs the initial data with the data collected through recursion.&lt;/li&gt;
&lt;li&gt;Line 4: defines the query that actually does the recursion. This query joins the categories table with the all_categories CTE.&lt;/li&gt;
&lt;li&gt;Line 5: query the CTE we just defined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the results of the single query:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; id | parent_id | name  
&amp;amp;#8212;-+&amp;amp;#8212;&amp;amp;#8212;&amp;amp;#8212;&amp;amp;#8211;+&amp;amp;#8212;&amp;amp;#8212;-
  7 |         3 | no
  8 |         3 | yes
  9 |         3 | maybe
 10 |         8 | good
 11 |         8 | bad
 12 |         8 | evil
(6 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I generally find this far more palatable than the various other solutions I’ve seen that involved either mountains of queries, mangling the schema or both.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/0FOpr-RhU0E" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2009/7/21/exploring-postgresql-8-4-recursive-queries</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2009-07-21:319</id>
    <published>2009-07-21T02:11:00Z</published>
    <updated>2009-07-21T02:12:39Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/rjfEWe2U8No/quick-hack-nokogiri-backed-hash-ish-class" rel="alternate" type="text/html" />
    <title>Quick Hack: Nokogiri backed Hash-ish class</title>
<content type="html">
            &lt;p&gt;Many months ago I was working on some code that needed to handle small bits of XML. For the sake of expediency I went with using Rails’ Hash.from_xml method. This worked great for quite a while.&lt;/p&gt;

&lt;p&gt;Eventually, the size of the XML I was handling got quite a bit bigger. Now, I’m dealing with several megabytes of XML in each file. With this much data Hash.from_xml is painfully slow. Maxing out the CPU for several minutes slow.&lt;/p&gt;

&lt;p&gt;So, I spent a few minutes on Friday afternoon and hacked together a class that acts like the data structure that Hash.from_xml returns. However, instead of building the entire data structure up front, it has some Hash and Array methods that call Nokogiri methods on demand. That said, even parsing the entire document is an order of magnitude faster.&lt;/p&gt;

&amp;lt;script src="http://gist.github.com/151055.js"&gt;&amp;lt;/script&gt;

&lt;pre&gt;&lt;code&gt;              user        system    total       real
Hash.from_xml 663.820000  3.220000  667.040000  (675.076590)
NokoHash      22.410000   0.190000  22.600000   ( 22.771999)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I also threw in some #method_missing magic to allow for method-call style access of the structure instead of just hash/key access.&lt;/p&gt;

&lt;h2&gt;Warning&lt;/h2&gt;

&lt;p&gt;This code is only tested as far as my specific needs for this specific system. I have precisely zero confidence that this will work smoothly for you. I just found this to be an interesting bit of code, I hope you do too.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gist.github.com/151049"&gt;http://gist.github.com/151049&lt;/a&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/rjfEWe2U8No" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2009/7/21/quick-hack-nokogiri-backed-hash-ish-class</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2009-05-12:113</id>
    <published>2009-05-12T19:48:00Z</published>
    <updated>2009-05-12T19:53:01Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/xgeGfVfGqMU/simple-association-versioning-with-acts_as_revisable" rel="alternate" type="text/html" />
    <title>Simple association versioning with acts_as_revisable</title>
<content type="html">
            &lt;p&gt;One of the reasons AAR was created was due to the hoops that we had to jump through to effectively version across associations while taking into account our business logic. We ended up with hundreds of lines of very complicated spaghetti code. It wasn't pretty.&lt;/p&gt;

&lt;p&gt;Here I'm going to demonstrate how you can very simply version two models together. &lt;/p&gt;

&lt;p&gt;We'll provide for Posts which can have multiple Links. Any time a Post is created or modified, a revision of it and it's associated links &lt;em&gt;at the time&lt;/em&gt; will be stored. Adding a link to a Post will also trigger a revision. &lt;/p&gt;

&lt;p&gt;Changing a link will not trigger a revision of the Post. This is trivial to add and should be considered a task for you (if you want to play with AAR).&lt;/p&gt;

&lt;h2&gt;Model walk-through&lt;/h2&gt;

&lt;p&gt;You can grab the complete code for this any time at &lt;a href="http://github.com/rich/aar-demo-1/tree/master"&gt;GitHub&lt;/a&gt; but, I'm going to walk through the models now.&lt;/p&gt;

&lt;h3&gt;post.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;class Post &amp;lt; ActiveRecord::Base
  acts_as_revisable
  has_many :links, :before_add =&amp;gt; :revise!
  after_revise :revise_links!

  private
    def revise_links!
      self.links.each(&amp;amp;:revise!)
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So first, we're defining our Post, making it revisable and associating it to it's links. We've also added two callbacks. &lt;/p&gt;

&lt;p&gt;The first, on the links association, causes the post to be revised &lt;em&gt;before&lt;/em&gt; a new link is added. This allows us to grab the state of the links before it changes. So we'll end up with an accurate snapshot of the post.&lt;/p&gt;

&lt;p&gt;The second callback is the after_revise callback which simply loops through the links, forcing a revision on them. This allows us to peg a particular post revision with a particular link revision.&lt;/p&gt;

&lt;p&gt;Notice there's really no magic here, we're just using the tools acts_as_revisable gives us.&lt;/p&gt;

&lt;h3&gt;link.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;class Link &amp;lt; ActiveRecord::Base
  acts_as_revisable

  belongs_to :post
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Simply declaring our Link, making it revisable and associating it with a post. Nothing special here.&lt;/p&gt;

&lt;h3&gt;post_revision.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;class PostRevision &amp;lt; ActiveRecord::Base
  acts_as_revision

  has_many :links, :class_name =&amp;gt; "LinkRevision", :foreign_key =&amp;gt; "post_id"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we're explicitly defining our PostRevision class and letting AAR know. Defining the association requires a few more options just to override some of ActiveRecord's defaults. Notice PostRevisions will always be associated with LinkRevisions.&lt;/p&gt;

&lt;h3&gt;link_revision.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;class LinkRevision &amp;lt; ActiveRecord::Base
  acts_as_revision

  belongs_to :post, :class_name =&amp;gt; "PostRevision"  
  before_create :reassociate_with_post, :if =&amp;gt; :post_in_revision?

  private
    def reassociate_with_post
      self.post = self.current_revision.post.find_revision(:previous)
    end

    def post_in_revision?
      self.current_revision.post.in_revision?
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's the most complicated part and even this isn't so bad. We're explicitly defining our LinkRevision and it's association.&lt;/p&gt;

&lt;p&gt;Next, we have a before_create callback. Keep in mind, this is the revision model so, before_create in this case is roughly equivalent to before_revise on the Link model. I've defined it this way for the sake of clarity. The work in this callback really concerns the revisions &lt;em&gt;not&lt;/em&gt; the revisable. So, while it could be defined in either model, it makes the most sense when reading the code for it to be here.&lt;/p&gt;

&lt;p&gt;The reassociate_with_post method being called by the callback is relatively easy to understand if you keep the big picture in mind. A post's links are being revised &lt;em&gt;after&lt;/em&gt; the post so, this callback is called after the post has been revised. So, we're simply grabbing the last revision of this post and associating the LinkRevision with that.&lt;/p&gt;

&lt;h2&gt;Let's see it in action&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; p = Post.create(:title =&amp;gt; "Simple association versioning with acts_as_revisable")
=&amp;gt; #&amp;lt;Post id: 55, title: "Simple association versioning with acts_as_revisabl..."&amp;gt;
&amp;gt;&amp;gt; p.links.create(:url =&amp;gt; "http://github.com/rich/aar-demo-1/tree/master")
=&amp;gt; #&amp;lt;Link id: 92, url: "http://github.com/rich/aar-demo-1/tree/master"&amp;gt;
&amp;gt;&amp;gt; p.revisions.size
=&amp;gt; 1
&amp;gt;&amp;gt; p.revisions.first.links
=&amp;gt; []
&amp;gt;&amp;gt; p.links
=&amp;gt; [#&amp;lt;Link id: 92, url: "http://github.com/rich/aar-demo-1/tree/master"&amp;gt;]
&amp;gt;&amp;gt; p.title = "That was easy"
=&amp;gt; "That was easy"
&amp;gt;&amp;gt; p.save
=&amp;gt; true
&amp;gt;&amp;gt; p.revisions.map {|r| r.links.size}
=&amp;gt; [1, 0]
&amp;gt;&amp;gt; p.revisions.first.links.first
=&amp;gt; #&amp;lt;LinkRevision id: 93, url: "http://github.com/rich/aar-demo-1/tree/master"&amp;gt;
&amp;gt;&amp;gt; p.links.create(:url =&amp;gt; "http://github.com/rich")
=&amp;gt; #&amp;lt;Link id: 95, url: "http://github.com/rich"&amp;gt;
&amp;gt;&amp;gt; p.revisions.map {|r| r.links.size}
=&amp;gt; [1, 1, 0]
&amp;gt;&amp;gt; p.links.size
=&amp;gt; 2
&amp;gt;&amp;gt; p.links.create(:url =&amp;gt; "http://github.com/technoweenie/acts_as_versioned/tree/master")
=&amp;gt; #&amp;lt;Link id: 98, url: "http://github.com/technoweenie/acts_as_versioned/tr..."&amp;gt;
&amp;gt;&amp;gt; p.links.size
=&amp;gt; 3
&amp;gt;&amp;gt; p.revisions.map {|r| r.links.size}
=&amp;gt; [2, 1, 1, 0]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have a couple ideas in progress for a followup post but, I'd love some requests if there's interest.&lt;/p&gt;

&lt;p&gt;Remember, you can grab the code on &lt;a href="http://github.com/rich/aar-demo-1/tree/master"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/xgeGfVfGqMU" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2009/5/12/simple-association-versioning-with-acts_as_revisable</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2009-04-09:107</id>
    <published>2009-04-09T18:16:00Z</published>
    <updated>2009-04-09T18:30:21Z</updated>
    <category term="PHP" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/0bq8VTRDH34/hoptoad-goes-great-with-php-too" rel="alternate" type="text/html" />
    <title>Hoptoad. Goes great with PHP too.</title>
<content type="html">
            &lt;p&gt;Over the years of Rails work I’ve been using a few services that I consider indispensable now. &lt;a href="http://hoptoadapp.com/"&gt;Hoptoad&lt;/a&gt; is one of those tools. It beats the hell out of pretty much every cobbled together error notifier I’ve seen. I can’t see launching an application without it.&lt;/p&gt;

&lt;h2&gt;The Horror&lt;/h2&gt;

&lt;p&gt;Sometimes, I need to work with PHP. It’s not pleasant but, there it is. One of the things I did to make this a bit more palatable is hack together a Hoptoad notifier for PHP. Recently, with some help from Lou Kosak, I’ve cleaned the code up a bit and think it might be useful in other projects now.&lt;/p&gt;

&lt;h2&gt;Grab it&lt;/h2&gt;

&lt;p&gt;You can find the code at &lt;a href="http://github.com/rich/php-hoptoad-notifier"&gt;http://github.com/rich/php-hoptoad-notifier&lt;/a&gt;. Just drop the Hoptoad.php file somewhere in your include_path and include the following code somewhere early in your application:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  require_once('Hoptoad.php');&lt;/p&gt;

&lt;p&gt;Hoptoad::installHandlers("YOUR_HOPTOAD_API_KEY");
&lt;/code&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/0bq8VTRDH34" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2009/4/9/hoptoad-goes-great-with-php-too</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2009-04-03:98</id>
    <published>2009-04-03T01:58:00Z</published>
    <updated>2009-04-03T15:38:42Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/IDwfJVrVjtE/flexible-activerecord-versioning-with-actsasrevisable" rel="alternate" type="text/html" />
    <title>Flexible ActiveRecord Versioning with ActsAsRevisable</title>
<content type="html">
            &lt;p&gt;I’ve been working on this on and off for the better part of the last year. Life has intruded many times but, I’ve finally got it to a point that I’m comfortable releasing as a 1.0.&lt;/p&gt;

&lt;p&gt;This plugin grew out of &lt;a href="http://voxdolo.me/"&gt;Stephen Caudill&lt;/a&gt; and my use of Rick Olsen’s &lt;a href="http://github.com/technoweenie/acts_as_versioned/tree/master"&gt;ActsAsVersioned&lt;/a&gt;. The application was centered around versioning of our user’s resources. Early on, AAV worked great for us but, as our requirements got more complicated we found ourselves hacking AAV more and more.&lt;/p&gt;

&lt;p&gt;Eventually Stephen came to the conclusion that we needed to break from AAV and roll our own. So he laid out the requirements and I built it. I’m going to talk about all of AAR’s features through a series of posts but, I thought I’d quickly highlight some of it’s unique features now.&lt;/p&gt;

&lt;h2&gt;Pervasive Callbacks&lt;/h2&gt;

&lt;p&gt;AAR was created to help build applications that need precise control of the life-cycle of it’s data. In pursuit of that, there is a full suite of callbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;revisable models
&lt;ul&gt;
&lt;li&gt;before_revise&lt;/li&gt;
&lt;li&gt;after_revise&lt;/li&gt;
&lt;li&gt;before_revert&lt;/li&gt;
&lt;li&gt;after_revert&lt;/li&gt;
&lt;li&gt;before_changeset&lt;/li&gt;
&lt;li&gt;after_changeset&lt;/li&gt;
&lt;li&gt;after_branch_created&lt;/li&gt;
&lt;li&gt;before_revise_on_destroy&lt;/li&gt;
&lt;li&gt;after_revise_on_destroy&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;revision models
&lt;ul&gt;
&lt;li&gt;before_restore&lt;/li&gt;
&lt;li&gt;after_restore&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;both revisable and revision models
&lt;ul&gt;
&lt;li&gt;before_branch&lt;/li&gt;
&lt;li&gt;after_branch&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AAR callbacks act just like ActiveRecord callbacks. They accept all the same arguments and they can prevent the action being taken just like AR callbacks.&lt;/p&gt;

&lt;h2&gt;Branching and Changesets&lt;/h2&gt;

&lt;p&gt;Branching is a well understood concept, no need to go in depth on this, here’s the relevant code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  @branch = @post.branch
  @branch.branch_source == @post # =&gt; true&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Changesets are a bit more interesting. In non-trivial code you may end up a block of code that may perform many actions that each cause a revision to be saved. If you wish to group those as a single revision, you can:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  @post.changeset do 
    @post.title = "A post"
    # save would normally trigger a revision
    @post.save
    # update_attribute triggers a save triggering a revision (normally)
    @post.updated_attribute(:title, "Another Title")
    # revise! normally forces a revision to be created
    @post.revise!
  end&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Deletes can be stored as a revision&lt;/h2&gt;

&lt;p&gt;This is pretty simple, #destroy no longer destroys the record. It flags it as deleted. Deleted records can then be accessed through the revision class’ #deleted named_scope.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class Post &amp;lt; ActiveRecord::Base
    acts_as_revisable :on_delete =&gt; :revise
  end&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;  @post.destroy
  PostRevision.deleted # =&gt; [@post]&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Explicit is better than implicit&lt;/h2&gt;

&lt;p&gt;ActsAsRevisable will not, by default, define the revision class for you. The most common configuration is as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class Post &amp;lt; ActiveRecord::Base
    acts_as_revisable
  end

  class PostRevision &amp;lt; ActiveRecord::Base
    acts_as_revision
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to call your revision class something else, you can:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class Post &amp;lt; ActiveRecord::Base
    acts_as_revisable :revision_class_name =&gt; 'OldPost'
  end

  class OldPost &amp;lt; ActiveRecord::Base
    acts_as_revision :revisable_class_name =&gt; 'Post'
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you absolutely must have AAR generate the class for you:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class Post &amp;lt; ActiveRecord::Base
    acts_as_revisable :generate_revision_class =&gt; true
  end&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;All data for a model is stored in one table&lt;/h2&gt;

&lt;p&gt;There isn’t a separate versions table. This comes from the belief that all Posts (or whatever your model happens to be) are Posts whether or not they’re the current version. &lt;/p&gt;

&lt;p&gt;This also makes it much easier to find records whether or not they’re the current version or not:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  Post.find(:all, :conditions =&gt; {...}, :with_revisions =&gt; true)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Wrapping up, requirements and installing&lt;/h2&gt;

&lt;p&gt;There’s a lot of flexibility here. In the application AAR was built for we were using it to version entire trees of objects together, not just individual records. I plan on digging into this and more in future posts.&lt;/p&gt;

&lt;p&gt;AAR 1.0 requires Rails 2.3. You can take a look at the code on &lt;a href="http://github.com/rich/acts_as_revisable/tree/master"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  sudo gem install rich-acts_as_revisable --source=http://gems.github.com&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once the gem is installed you’ll want to activate it in your Rails app by adding the following line to config/environment.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  config.gem "rich-acts_as_revisable", :lib =&gt; "acts_as_revisable", :source =&gt; "http://gems.github.com"&lt;/code&gt;&lt;/pre&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/IDwfJVrVjtE" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2009/4/3/flexible-activerecord-versioning-with-actsasrevisable</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-09-03:67</id>
    <published>2008-09-03T02:09:00Z</published>
    <updated>2008-09-04T12:11:39Z</updated>
    <link href="http://feedproxy.google.com/~r/without_scope/~3/bhFZXbFGeiQ/chrome-is-google-s-big-stick" rel="alternate" type="text/html" />
    <title>Chrome is Google's Big Stick</title>
<content type="html">
            &lt;p&gt;I’ve been playing with Google Chrome all day. I’ve used it exclusively for about eight hours now. I’m definitely impressed. It’s fast, simple and stable. The UI changes show obvious inspiration from all of the major browsers with solid usability improvements. &lt;/p&gt;

&lt;p&gt;The concept and implementation of distinct processes for each plugin and page causes an inappropriate stirring in my loins.&lt;/p&gt;

&lt;p&gt;I’m impressed.&lt;/p&gt;

&lt;p&gt;I’ve seen those details covered ad-nauseam though and probably better than I ever could. Here’s a &lt;a href="http://waffle.wootest.net/2008/09/02/cr24/"&gt;decent rundown&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Wrapping Myself in Tinfoil&lt;/h2&gt;

&lt;p&gt;I don’t think Google wants or expects to gain significant market share with Chrome. I think they’re now trying to drive innovation in the browser world by competing rather than simply consuming.&lt;/p&gt;

&lt;p&gt;They’ve been providing carrots to the browser makers in the form of the various Google apps for years. I think they’ve been disappointed at the relatively slow and uninspired developments of IE, Firefox, Opera and Safari.&lt;/p&gt;

&lt;p&gt;I believe this is Google’s stick. They’re going to smack the other browser developers with Chrome to drive them in the direction that they believe is most beneficial to Google.&lt;/p&gt;

&lt;p&gt;I really don’t think I’m way off in tin-foil hat territory here but I am curious what others think.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/bhFZXbFGeiQ" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/9/3/chrome-is-google-s-big-stick</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-08-28:57</id>
    <published>2008-08-28T23:34:00Z</published>
    <updated>2008-09-01T18:55:42Z</updated>
    <link href="http://feedproxy.google.com/~r/without_scope/~3/_87hiLgcpWs/tough-decisions" rel="alternate" type="text/html" />
    <title>Tough Decisions</title>
<content type="html">
            &lt;h3&gt;Clarifications&lt;/h3&gt;

&lt;p&gt;Reading what I wrote below I see where my mind was just a few days ago. I wasn’t entirely wrong to talk about where my mind was but, I did trivialize the job offer quite a bit in an effort to get people to backup the idea of consulting.&lt;/p&gt;

&lt;p&gt;That was kinda stupid of me to do though. It actually *is* an interesting job with a company in a field I’ve wanted to work in for a long time. It’s a solid group of passionate people and anyone that knows me knows seeing passion for what you’re doing is a big deal for me. These people don’t just have passion though, they seem to have the talent to implement their vision.&lt;/p&gt;

&lt;p&gt;So, I’m leaving the post as is for posterity’s sake but, as you read, keep in mind I don’t even agree with a fair bit of what I wrote myself.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;I’ve been an out of work Ruby developer for about three weeks now. When I got word that my paychecks would stop coming I immediately reached out to some friends and colleagues for a few contracts and this is what I’ve been doing the last few weeks.&lt;/p&gt;

&lt;h2&gt;Three Weeks&lt;/h2&gt;

&lt;p&gt;In those three weeks I’ve been working on some truly interesting projects and learning a ton. I’ve been working with other people’s code that borders on pure poetry and some code that appears to be an implementation of “&lt;a href="http://www.muppetlabs.com/~breadbox/bf/"&gt;Brainfuck&lt;/a&gt; on Ruby on Rails”.&lt;/p&gt;

&lt;p&gt;In just three weeks I’ve worked in multiple languages with several technologies I hadn’t touched before. I’ve even found and used a &lt;a href="http://www.doctrine-project.org/"&gt;respectable PHP ORM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More importantly, I’ve gotten a crash course in the contracting business from some smart people that have been doing this for years. I’m also playing “&lt;a href="http://www.infoq.com/presentations/fernandez-sales-do-the-hustle"&gt;Do The Hustle&lt;/a&gt;” on a perpetual loop, thanks Obie. &lt;/p&gt;

&lt;p&gt;Doing this for just three weeks of course means I’m still absolutely horrible at the sales process but, it’s a start.&lt;/p&gt;

&lt;h2&gt;No Plan&lt;/h2&gt;

&lt;p&gt;So far, I’m loving the contracting thing and I want desperately to make my living doing this for a while. The problem is, I didn’t plan this. &lt;/p&gt;

&lt;p&gt;I planned on sticking with JamLab and seeing that through. I planned on a successful launch and supporting a truly awesome product. I planned on getting a steady paycheck and health insurance.&lt;/p&gt;

&lt;p&gt;I have all the usual responsibilities of someone my age. I have a wife, a daughter, a mortgage, etc. All these people and things generally want to eat and/or get paid on a pretty regular basis.&lt;/p&gt;

&lt;p&gt;Had I planned this and had all the research done and proof that I could handle my responsibilities consistently I wouldn’t be so nervous. I’m fine now but what about tomorrow? The day after? &lt;/p&gt;

&lt;p&gt;Is there really that much work for a good developer but horrible sales guy?&lt;/p&gt;

&lt;h2&gt;My Dilemma&lt;/h2&gt;

&lt;p&gt;I got a job offer today. Not a great one and not a horrible one. I would still get to use Ruby, which is great, and the work looks interesting. The job does strike me as having the potential of being one of those perpetual crunch time environments though. Really, this post isn’t about this job though, others will come, it’s more about full-time v. contractor.&lt;/p&gt;

&lt;p&gt;It would pay the bills though and, I’m assuming, on a pretty regular basis. I just honestly don’t know what to do.&lt;/p&gt;

&lt;p&gt;Three weeks ago it was easy, I was a cog in a wheel and didn’t know what I was missing out on. Now I’ve got a taste and I do like it.&lt;/p&gt;

&lt;p&gt;So all ten of you that read my blog, tell me what to do. Help me map out my future. Direct me on how to balance my happiness. &lt;/p&gt;

&lt;p&gt;Or just post lolcat images, that’s fine too.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/_87hiLgcpWs" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/8/28/tough-decisions</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-08-22:47</id>
    <published>2008-08-22T03:36:00Z</published>
    <updated>2008-08-22T13:55:00Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/VM4ux2FLTVc/don-t-use-proxy_target-in-ar-association-extensions" rel="alternate" type="text/html" />
    <title>Don't use proxy_target in AR association extensions</title>
<content type="html">
            &lt;p&gt;This is as much a note to my future self as a warning post to others doomed to make the same mistake I did. I was creating a few methods to extend a has_many association with. Based on the current Rails docs I used the proxy_target accessor to get at the records of the association.&lt;/p&gt;

&lt;p&gt;The only problem with that is proxy_target is not populated unless the association had previously been traversed through the same model instance. After I tossed in a line of code into the method that explicitly loaded the association I decided this was a bug in Rails.&lt;/p&gt;

&lt;h2&gt;It wasn’t a bug&lt;/h2&gt;

&lt;p&gt;I started thinking about a patch but decided this couldn’t possibly have been missed that long. So instead I googled quite a bit more and eventually found &lt;a href="http://www.ruby-forum.com/topic/160151"&gt;“Should proxy_owner be eager loaded?”&lt;/a&gt;. This accurately described my issue. &lt;/p&gt;

&lt;h2&gt;The answer&lt;/h2&gt;

&lt;p&gt;Put simply, proxy_target is implied in the scope of association extensions. Here’s some of my own example code that demonstrates:&lt;/p&gt;

&amp;lt;script src="http://gist.github.com/6733.js"&gt;&amp;lt;/script&gt;

&lt;p&gt;Also, if you go off the beaten path in the Rails docs a bit you’ll find this behavior is documented in &lt;a href="http://apidock.com/rails/ActiveRecord/Associations/AssociationProxy"&gt;ActiveRecord::Associations::AssociationProxy&lt;/a&gt;. This should probably be mentioned in &lt;a href="http://apidock.com/rails/ActiveRecord/Associations/ClassMethods"&gt;ActiveRecord::Associations::ClassMethods&lt;/a&gt; where proxy_target is discussed. Maybe I’ll make my first doc patch tomorrow.&lt;/p&gt;

&lt;p&gt;Feel free to use the comments to ridicule me.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/VM4ux2FLTVc" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/8/22/don-t-use-proxy_target-in-ar-association-extensions</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-08-18:43</id>
    <published>2008-08-18T16:30:00Z</published>
    <updated>2008-08-18T16:30:30Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/obmPe14Qb6k/some-shoulda-plugin-love" rel="alternate" type="text/html" />
    <title>Some Shoulda Plugin Love</title>
<content type="html">
            &lt;p&gt;I’ve been using Shoulda for some new projects and while it’s a learning experience I’m really pleased with the results. One thing I noticed right away is that I was testing for the presence and functionality of several Rails plugins I chose that are being used on many models. &lt;/p&gt;

&lt;p&gt;I ended up writing custom Shoulda macros for three of the plugins: &lt;a href="http://github.com/mbleigh/acts-as-taggable-on/tree/master"&gt;ActsAsTaggableOn&lt;/a&gt;, &lt;a href="http://github.com/jackdempsey/acts_as_commentable/tree/master"&gt;ActsAsCommentable&lt;/a&gt; and &lt;a href="http://github.com/norbauer/salty_slugs/tree/master"&gt;SaltySlugs&lt;/a&gt;. Below are the macros and an example of their usage in a test.&lt;/p&gt;

&lt;h2&gt;Shoulda Macros&lt;/h2&gt;

&amp;lt;script src="http://gist.github.com/5988.js"&gt;&amp;lt;/script&gt;

&lt;h2&gt;Example Usage&lt;/h2&gt;

&amp;lt;script src="http://gist.github.com/6008.js"&gt;&amp;lt;/script&gt;

&lt;pre&gt;&lt;code&gt;$ ruby -Itest test/unit/album_test.rb 
Loaded suite test/unit/album_test
Started
&amp;amp;#8230;&amp;amp;#8230;&amp;amp;#8230;&amp;amp;#8230;&amp;amp;#8230;&amp;amp;#8230;&amp;amp;#8230;
Finished in 0.109251 seconds.

21 tests, 32 assertions, 0 failures, 0 errors
&lt;/code&gt;&lt;/pre&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/obmPe14Qb6k" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/8/18/some-shoulda-plugin-love</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-08-01:40</id>
    <published>2008-08-01T21:53:00Z</published>
    <updated>2008-08-02T14:46:03Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/ywMEgatiWH0/be-a-developer-be-flexible-be-yourself" rel="alternate" type="text/html" />
    <title>Be a Developer. Be Flexible. Be Yourself.</title>
<content type="html">
            &lt;p&gt;Jay Fields originally got me thinking and writing the first draft of this with his “&lt;a href="http://blog.jayfields.com/2008/07/developers-needed-hackers-need-not.html"&gt;Developers needed; Hackers need not apply&lt;/a&gt;” post. By his definition, I’m a long time hacker. I’m in recovery now and feel like I’m far more of a developer at this point.&lt;/p&gt;

&lt;h2&gt;Confession time…&lt;/h2&gt;

&lt;p&gt;For too long I worked in very small companies where I was the only developer. A few times I was the only one with any technical experience and yeah, that was in technology startups. This led to them leaning too much on me for the overall direction of the products which in turn led me to think I’m qualified to make those decisions on my own.&lt;/p&gt;

&lt;p&gt;If you’re a developer, that’s a path destined for failure. You’ll likely make things more complicated than they need to be which will take longer to develop. Talk to everyone you can about the project and really listen. This sounds absolutely ridiculous and basic when typed out but, some people can’t even make that step, I know I couldn’t.&lt;/p&gt;

&lt;h2&gt;Recovery&lt;/h2&gt;

&lt;p&gt;Only through time and frustration did I realize there was something wrong with my thinking. I largely credit getting more involved with the development community as a whole with my real recovery. I think I was too isolated to come to the realization on my own. &lt;/p&gt;

&lt;p&gt;Meeting other developers who I truly respected was the real turning point. &lt;a href="http://exdolo.com/"&gt;Stephen Caudill&lt;/a&gt;, &lt;a href="http://justhack.com/"&gt;Chris Saylor&lt;/a&gt;, &lt;a href="http://brunomiranda.com/start"&gt;Bruno Miranda&lt;/a&gt; and Ryan Leavengood to name a few. These are all incredibly talented developers with varied experiences who’ve taught me the humility all true developers need to be successful. &lt;/p&gt;

&lt;p&gt;The Ruby community as a whole deserves credit as well. These ideals are better expressed by this community than any other I’ve seen.&lt;/p&gt;

&lt;p&gt;To be a good developer is to be humble. To realize you alone will not make a project successful. Sheer force of will doesn’t translate into a usable interface or a solid brand.&lt;/p&gt;

&lt;h2&gt;The part where I’m a bit of a contrarian&lt;/h2&gt;

&lt;p&gt;Shortly after the “Developers” post Jay followed up with “&lt;a href="http://blog.jayfields.com/2008/07/civics-not-cadillacs.html"&gt;Civics not Cadillacs&lt;/a&gt;.” He’s absolutely on point with this post as well but, this one is more of a high-wire act.&lt;/p&gt;

&lt;p&gt;Let me really abuse his car metaphor a bit. &lt;/p&gt;

&lt;p&gt;What happens when you’re told the airbags and seat-belts should be considered a version 2 feature? How about when you’re asked to propose a stopping mechanism other than brakes with “I saw a promising solution on the Flintstones once” tossed in for good measure.&lt;/p&gt;

&lt;p&gt;I know Jay wasn’t suggesting to abandon development best practices at the drop of the hat. I do think that it needs to be clear that some things a good developer just won’t sacrifice. &lt;/p&gt;

&lt;p&gt;It’s our jobs as developers to balance the business needs and proper development. That balancing act needs to include extensive collaboration with the rest of the business.&lt;/p&gt;

&lt;h2&gt;They probably hate you already&lt;/h2&gt;

&lt;p&gt;Anyone that knows me in person knows that I’m very opinionated. I do tend to tone it down online though. I’ve written several blog posts and chose to scrap them because I worried I would offend someone. Many times it was someone I respected.&lt;/p&gt;

&lt;p&gt;I did this because text and my questionable writing skills just don’t convey the tongue-in-cheek nature with which I want to deliver some of my thoughts.&lt;/p&gt;

&lt;p&gt;Then I read “&lt;a href="http://b.lesseverything.com/2008/8/1/losing-twitter-followers-is-a-good-thing"&gt;Losing Twitter Followers is a Good Thing&lt;/a&gt;” by Steve Bristol. Yet again, it’s another simple and obvious concept; just be yourself. I wish I knew why I need other people to blog about common sense for me to finally get it. &lt;/p&gt;

&lt;p&gt;As a developer you’re paid for your opinions. Don’t be afraid to share them. Just have the common sense to temper them with the realities of the business while maintaining your integrity. &lt;/p&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/ywMEgatiWH0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/8/1/be-a-developer-be-flexible-be-yourself</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-07-27:39</id>
    <published>2008-07-27T03:17:00Z</published>
    <updated>2008-07-27T03:17:45Z</updated>
    <link href="http://feedproxy.google.com/~r/without_scope/~3/ssA8CE1HQ5U/i-need-to-be-more-positive-or-hooray-shoulda" rel="alternate" type="text/html" />
    <title>I Need to be More Positive or Hooray Shoulda</title>
<content type="html">
            &lt;p&gt;I really don’t mean for this blog to devolve into Ruby’s &lt;a href="http://www.bileblog.org/"&gt;BileBlog&lt;/a&gt;. The problem is, more talented bloggers than I seem to have the positive aspects of the Ruby community very well covered and I really don’t want to simply retread well-trodden ground. With that said, there are a few things that I feel like aren’t being shouted from the rooftops the way they should be. Here’s one of them…&lt;/p&gt;

&lt;h2&gt;Simplicity Rules, Hooray &lt;a href="http://www.thoughtbot.com/projects/shoulda"&gt;Shoulda&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;In my opinion, RSpec represents a huge improvement over Test::Unit. I have a thing for aesthetically pleasing code and RSpec’s DSL satisfies me. &lt;/p&gt;

&lt;p&gt;Not all is well in RSpec land though. RSpec is a very complicated piece of code and we’ve experienced some very difficult to debug issues with it. For all it’s ugliness, Test::Unit works.&lt;/p&gt;

&lt;p&gt;This is where Shoulda comes in. With a relatively small and simple code-base we’re getting syntactic sugar on top of Test::Unit that provides most of the beauty of RSpec.&lt;/p&gt;

&lt;p&gt;More importantly, we get an extensive set of Rails specific macros which makes building specs for a Rails app far simpler. Most every Rails macro has a corresponding Shoulda macro. &lt;/p&gt;

&lt;p&gt;Very DRY with a clean, easy to understand code-base. I love it. Also, this revelation of mine is a long time coming, many thanks to &lt;a href="http://smartic.us/"&gt;Bryan Liles&lt;/a&gt; and &lt;a href="http://b.lesseverything.com/"&gt;Steven Bristol&lt;/a&gt; for putting me in line.&lt;/p&gt;

&lt;p&gt;I haven’t had a chance to use it in a project just yet but, I’ve done a lot of testing and research and am really looking forward to my future with Shoulda.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/ssA8CE1HQ5U" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/7/27/i-need-to-be-more-positive-or-hooray-shoulda</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-07-27:38</id>
    <published>2008-07-27T02:10:00Z</published>
    <updated>2008-07-27T02:10:56Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/N04_8Wdd_aA/gitacular" rel="alternate" type="text/html" />
    <title>Gitacular!</title>
<content type="html">
            &lt;p&gt;The title here may be a bit misleading, I just really wanted to play with the word “git.” This post will largely be focused on my issues with git.&lt;/p&gt;

&lt;h2&gt;RTFM NOOB&lt;/h2&gt;

&lt;p&gt;Git seems to be a new sacred cow. Any complaints are generally responded to with the assumption that the complainer is is definitely the one at fault. This may be attributed to the user’s stupidity or, more creatively, the user’s cleverness.&lt;/p&gt;

&lt;p&gt;Most recently I’ve seen &lt;a href="http://twitter.com/pjhyett/statuses/865456956"&gt;PJ Hyett tweet&lt;/a&gt; the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;when people get upset at git, it&amp;amp;#8217;s because they&amp;amp;#8217;re trying to do something clever and bad things happen. stop trying to be clever.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This may in fact be true in some cases but, claiming this is always the case is foolish at best.&lt;/p&gt;

&lt;h2&gt;A Tangent on GitHub&lt;/h2&gt;

&lt;p&gt;Since I just cited one of the minds behind GitHub I thought I should give some thoughts on GitHub. &lt;/p&gt;

&lt;p&gt;GitHub is pure unadulterated awesome. &lt;/p&gt;

&lt;p&gt;In a way, GitHub is the antithesis of the mess that is Git. The guys behind GitHub seem to pay attention to every little detail of the user interface. Git’s user interface in contrast appears to be put in place grudgingly by the Git developers who are outraged that users even need to interface with their masterpiece.&lt;/p&gt;

&lt;p&gt;GitHub seems to be the developer’s social network and I love it.&lt;/p&gt;

&lt;h2&gt;On User Interface&lt;/h2&gt;

&lt;p&gt;The most obvious flaw is the lack of consistency in the commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  git stash apply
  git rebase --continue
  git svn clone
  git commit -a -m
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Can we kindly pick one style? Either sub-commands (like apply) or options to commands (like –continue), pick one and stick with it. This reminds me of the inconsistencies in the function naming of PHP. I don’t want to be reminded of PHP, I have enough nightmares as it is.&lt;/p&gt;

&lt;p&gt;Other notable issues are displaying files in conflict as “unmerged” instead of say “conflict” as well as using “git add” to resolve conflicts instead of something like “git resolve.”&lt;/p&gt;

&lt;h2&gt;Another Tangent on user Interface&lt;/h2&gt;

&lt;p&gt;It seems odd to me that a community obsessed with perfection and beauty the way the Rails community is would accept and in some cases, defend a tool like this. &lt;/p&gt;

&lt;p&gt;As Ruby and Rails developers we all know interface, at all levels, matters. I’m also sure we’ve all re-factored working code because it was not idiomatic Ruby, in other words it offended our sense of style and beauty (yes, I’m simplifying the reasons for re-factoring ugly code, I know). So, I’m genuinely curious, when other equally powerful tools exist, what drove the early adoption of Git in the Ruby community?&lt;/p&gt;

&lt;h2&gt;Oh, There Are Bugs&lt;/h2&gt;

&lt;p&gt;Please, follow this and tell me what I’m doing wrong:&lt;/p&gt;

&amp;lt;script src="http://gist.github.com/2708.js"&gt;&amp;lt;/script&gt;

&lt;p&gt;So, everything goes as expected until the conflict that happens during the rebase-ing of the branch to the latest changes made in master. &lt;/p&gt;

&lt;p&gt;At line 50 you see me fix the conflict. I then verify the contents of the conflicted file on line 51. I add the file on line 53. Then I try to continue and the fun begins.&lt;/p&gt;

&lt;p&gt;At this point I’ve fixed the conflict and added the file yet, git is swearing no changes have been made. When I first ran across this, it resulted in lots of research trying to figure out what I was doing wrong. Only after far too much time wasted on this did I get desperate and add some random whitespace and add the file again. Turns out this pretty reliably corrects this issue.&lt;/p&gt;

&lt;p&gt;Another confidence inspiring issue is also rebase conflict related. Unfortunately, I can’t easily duplicate this issue so you’ll have to take my word for it. &lt;/p&gt;

&lt;p&gt;Same circumstances, I fix a conflict and add the file. When I try to continue I get a different error message from above but still suggesting I forgot to use “git add.” Again, after much research and random attempts to move forward, I found “git status” fixes this and allows me to continue. &lt;/p&gt;

&lt;p&gt;Yes, you read that right, a command meant to simply report the status of the repo is fixing my repo. It’s obviously updating something, somewhere deep in the .git directory that tells “git rebase –continue” that I have in-fact added the file. This is difficult to duplicate but, I have seen it several times.&lt;/p&gt;

&lt;h2&gt;“Rich, why do you hate Git?”&lt;/h2&gt;

&lt;p&gt;I don’t hate Git. I happen to think it’s a great tool and an unbelievable improvement over the tools we used to be saddled with. I just happen to think that there are tools out there that are just that much better than Git.&lt;/p&gt;

&lt;p&gt;I’m also posting this because I got a few responses (both public and private) to my complaints on twitter acting like I’m an imbecile with no clue what I’m doing. I’m definitely not a Git power user, I’ll give you that but, I always make an effort to be familiar with my tools and the best practices involved. With my relatively simple usage, I shouldn’t be running into these problems.&lt;/p&gt;

&lt;p&gt;The only thing tying me to Git is for compatibility with the broader Ruby community. I obviously don’t expect that to change but, we need to acknowledge issues with our tools and address them, not ignorantly ridicule the people pointing them out.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/N04_8Wdd_aA" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/7/27/gitacular</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-06-15:33</id>
    <published>2008-06-15T02:44:00Z</published>
    <updated>2008-06-15T02:58:56Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/HgZ2Lieoew0/failures-of-a-monolingual-culture" rel="alternate" type="text/html" />
    <title>Failures of a Monolingual Culture</title>
<content type="html">
            &lt;p&gt;There’s a joke that I’ve heard several times over the years. I don’t think I’ve ever told it for a laugh, really just as part of a larger discussion. It seems to apply here.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;What do you call someone who speaks three languages?&lt;br /&gt;
    Tri-lingual.  &lt;/p&gt;
    
    &lt;p&gt;What do you call someone who speaks two languages?&lt;br /&gt;
    Bi-lingual.  &lt;/p&gt;
    
    &lt;p&gt;What do you call someone who speaks one language?&lt;br /&gt;
    American.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, as an American who speaks only one language, I feel kind of offended but, I do get the bigger concept of the joke. That concept appeals to me as a developer. I’ve always found value in being familiar with multiple languages and tools; it’s always made it easier to chose the right tool for the job.&lt;/p&gt;

&lt;p&gt;While the ideas here apply to developers in general, being part of the Ruby/Rails community I’m going to focus on that community.&lt;/p&gt;

&lt;h2&gt;Observing the Herd&lt;/h2&gt;

&lt;p&gt;I’ve always been bothered by the disdain shown for “foreign” technologies by the Rails community. The two biggest being the database and JavaScript. &lt;/p&gt;

&lt;p&gt;The cheers I heard at the RailsConf MagLev presentation to someone shouting “screw relational databases” represent this problem well. There were many interesting aspects to MagLev but, what I heard the most about was the potential to do away with relational databases and do everything in Ruby. This is only the tip of the ice-burg as far as hating relational databases in the community. &lt;/p&gt;

&lt;p&gt;The impetus for writing this post itself was a friend and fellow Ruby developer tweeting “wishing i could write iPhone apps in ruby.” Hearing something along those lines is all too common.&lt;/p&gt;

&lt;p&gt;There are obviously exceptions and I applaud those exceptions but, I’m not talking about them in this post.&lt;/p&gt;

&lt;h2&gt;A Crippling Love For Ruby&lt;/h2&gt;

&lt;p&gt;The Rails JavaScript helpers have always been a sensitive topic for me. I’ve honestly never used them beyond the prototype phase in a project. I’ve always tried to go the unobtrusive route and hand-code my JavaScript. I do use jQuery though, I’m a bit insane but I’m not a masochist. Put simply, I’m a web developer and JavaScript is &lt;strong&gt;the&lt;/strong&gt; language for programming in a web browser.&lt;/p&gt;

&lt;p&gt;Another sore spot is the database. The common Rails idiom seems to be to do everything in Ruby and to avoid things that can’t be expressed in Ruby. This can lead to incredibly naive implementations that would run exponentially better in the database. &lt;/p&gt;

&lt;p&gt;Before I hear the bellows of “premature optimization.” Knowing your tools and using them appropriately is not premature optimization. Things such as triggers and stored procedures can be incredibly powerful and should seriously considered. &lt;/p&gt;

&lt;p&gt;Even indices seem to commonly trip up seasoned Rails developers. I’ve heard of at least a dozen instances of an application being sped up simply by properly indexing the tables. It’s just plain sad that something as simple as an index turns into a real stumbling block. This happens because the database is seen simply as a necessary evil that can be ignored until performance demands giving it a little attention.&lt;/p&gt;

&lt;h2&gt;To be continued…&lt;/h2&gt;

&lt;p&gt;I have a lot more I could cover here but, I see this post as simply the start of a much larger discussion. So, what do you think?&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/HgZ2Lieoew0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/6/15/failures-of-a-monolingual-culture</feedburner:origLink></entry>
  <entry xml:base="http://withoutscope.com/">
    <author>
      <name>rich</name>
    </author>
    <id>tag:withoutscope.com,2008-06-02:31</id>
    <published>2008-06-02T03:42:00Z</published>
    <updated>2008-06-02T03:44:19Z</updated>
    <category term="Rails" />
    <link href="http://feedproxy.google.com/~r/without_scope/~3/oSuhHpefstA/railsconf-2008-is-over-a-stream-of-conciousness" rel="alternate" type="text/html" />
    <title>RailsConf 2008 is Over, a Stream of Conciousness</title>
<content type="html">
            &lt;p&gt;This was my second RailsConf and the change in the community are stunning. Last year was all about “fuck everyone else, we know the way.” As a rule, I like this attitude. The problem was that it was applied to things such as “sound engineering” and “good ideas.”&lt;/p&gt;

&lt;p&gt;Last year there was very little interest in alternatives. Alternatives to ruby, rails and rails’ ideology were all soundly shat on by everyone I spoke to. This year things like &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;, &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt;, &lt;a href="http://ruby.gemstone.com/"&gt;MagLev&lt;/a&gt;, &lt;a href="http://www.merbivore.com/"&gt;Merb&lt;/a&gt; and &lt;a href="http://datamapper.org/"&gt;DataMapper&lt;/a&gt; all had solid showings, large crowds and lots of excitement.&lt;/p&gt;

&lt;h2&gt;Things have changed&lt;/h2&gt;

&lt;p&gt;The general tone was more accepting of new ideas. The Rails Core panel showed the trademark cockiness [well-deserved in my opinion] but, expressed finally openness to real valuable changes to things like ActiveRecord. &lt;/p&gt;

&lt;p&gt;Not much in this world could excite me more than discussion of an &lt;a href="http://datamapper.org/why.html"&gt;identity map&lt;/a&gt; in ActiveRecord.&lt;/p&gt;

&lt;p&gt;I also saw real excitement over the alternative Ruby implementations. I’m sure this has something to do with their massive progress but, it really seemed people were finally ready to hear new ideas. I didn’t hear a single person expressing anything but &lt;a href="http://blog.obiefernandez.com/content/2008/05/maglev-is-gemst.html"&gt;excitement&lt;/a&gt; about these project.&lt;/p&gt;

&lt;h2&gt;Everyone loves the enterprise…&lt;/h2&gt;

&lt;p&gt;…not just enterprise software, although there was actual praise for the concept of the enterprise (a big change in this community) but, more traditional software engineering ideas as well.&lt;/p&gt;

&lt;p&gt;The keynotes by &lt;a href="http://www.joelonsoftware.com/"&gt;Joel Spolsky&lt;/a&gt; and &lt;a href="http://www.threeriversinstitute.org/Kent%20Beck.htm"&gt;Kent Beck&lt;/a&gt; were great. More surprisingly, I’m in the solid majority with that opinion.&lt;/p&gt;

&lt;h2&gt;I have arrived… kinda&lt;/h2&gt;

&lt;p&gt;I did a lightning talk on a JamLab project and it was very well received. There’s actual interest and there was almost no laughing. To be honest, I was shaking while giving my stupid little five minute talk. I’ve never talked in front of a crowd that big before. I definitely have a new found respect for the people that get up and talk for an hour.&lt;/p&gt;

&lt;p&gt;In the talk “The Worst Rails Code You’ve Ever Seen (and How Not To Write It Yourself)” by Obie Fernandez he talked about my plugin for almost a whole 3 seconds and I felt like a 90s schoolgirl at a NKOTB concert.&lt;/p&gt;

&lt;p&gt;I also worked much harder at meeting people and talking to people. I’m not a social person so, it’s not easy but, the awesome Oregon beers and meeting great people like &lt;a href="http://b.lesseverything.com/"&gt;Steven Bristol&lt;/a&gt;, &lt;a href="http://woss.name/"&gt;Grame Mathieson&lt;/a&gt; and &lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt; made things a bit easier on me.&lt;/p&gt;

&lt;h2&gt;That reminds me&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt;, &lt;a href="http://objo.com/"&gt;Joe O’Brien&lt;/a&gt; and &lt;a href="http://mysterycoder.blogspot.com/"&gt;Chris Nelson&lt;/a&gt; gave, what is in my opinion, the best “better your craft” talk I’ve ever seen. It was called “Dialogue Concerning the Two Chief Modeling Systems.” Words don’t do it justice, especially not mine. There’s a decent summary &lt;a href="http://www.benjaminbooth.com/tableorbooth/2008/05/summary-dialogue-concerning-the-two-chief-modeling-systems.html"&gt;here&lt;/a&gt; but, it’s not just the content that made this talk a thing of legends.&lt;/p&gt;

&lt;h2&gt;More to come&lt;/h2&gt;

&lt;p&gt;I just wanted to get some of my initial thoughts posted. I have some more specific technical issues I want to mull over before posting about. I can’t say my level of excitement after RailsConf this year matches last year but, my hope for and interest in the community as a whole has grown tremendously. I need to try a pull my weight by contributing more.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/without_scope/~4/oSuhHpefstA" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://withoutscope.com/2008/6/2/railsconf-2008-is-over-a-stream-of-conciousness</feedburner:origLink></entry>
</feed>
