<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Article RSS Feed test</title>
    <link>http://davidbeckwith.com/rss/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Hello I'm testing my RSS feed.</description>
    
    
        <item>
          <title>Loving the BAMness of Mechanize</title>
          <description>It's time to get excited about a README file.  I just discovered Ruby's Mechanize gem, and all I can say is &quot;wow.&quot;  It's so BAM.  How did I go for so long without appreciating the majesty of this library?  Mechanize is a Ruby library that pretends to be a browser, follows redirects, simulates storing cookies, fills out forms, clicks on buttons and links, uploads files, selects out text with CSS selectors .... the only thing it can't do is wipe your butt for you.  But if you could figure out how to make a browser do that, then you could automate it with Mechanize.  

http://mechanize.rubyforge.org/mechanize/files/GUIDE_txt.html
http://mechanize.rubyforge.org/files/EXAMPLES_txt.html

Check out this nice syntax:

 page = agent.get('http://google.com/')
 puts page.body

BAM.  You've just requested an HTML page.

You want links?  We got links:

  page.links.each do |link|
    puts link.text
  end

BAM.  That gives you a list of links on the page.

You want to click on a link?

  page = agent.click page.links.text('News')

BAM, you're on the next page.

You want to fill out a form?

  google_form = page.form('f')             # As in, &lt;form ... name=&quot;f&quot;&gt;
  google_form.q = 'vitamin C'             # Fill out the text box called &quot;q&quot; on the google search page.
  page = agent.submit(google_form, google_form.buttons.first)             # Click on the submit button.

BAM, you got search results about vitamin C!

What?  That search engine banned you for being a Ruby script?  Pretend you're a Mac:

agent.user_agent_alias = 'Mac Safari'

BAM, you're back in business.  What are the applications?  Local integration testing exercising your full application stack, making sure your production machine is still up and running on every project you ever worked on, scraping, spamming, automated posting, spamming for fun and profit . . . . . you name it.

Mechanize is a powerful tool that should be on the top shelf of every Ruby programmer's tool kit.  I would say that with Mechanize, Capistrano, Flash widgets, RSpec, and Ruby on Rails you could pretty much rule the world.  



</description>
          <pubDate>Thu, 08 May 2008 11:54:37 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2008/05/08/loving-the-bamness-of-mechanize/</guid>
          <link>http://davidbeckwith.com/articles/2008/05/08/loving-the-bamness-of-mechanize/</link>
        </item>
    
        <item>
          <title>resource_controller plugin</title>
          <description>&lt;p&gt;For those of you learning or using Ruby on Rails, here are my notes on Fabio Akita&amp;#8217;s excellent screencast tutorial for James Golick&amp;#8217;s resource_controller plugin.  I find it to be useful to be able to refer to a written document quickly instead of having to watch the entire hour presentation if you forget something.  Feel free to report errors or inaccuracies in my notes.  I hope you find the notes to be handy too.&lt;/p&gt;


	&lt;p&gt;Notes on Fabio Akita&amp;#8217;s screencast: http://www.akitaonrails.com/2008/1/25/easy-restful-rails-screencast&lt;/p&gt;


	&lt;p&gt;Topic: James Golick&amp;#8217;s resource_controller plugin for Ruby on Rails: http://jamesgolick.com/resource_controller&lt;/p&gt;


	&lt;p&gt;Problem #1: RESTful controllers almost always have 7 methods that look nearly the same.  There is a lot of repetitive code.  This is not &lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;.  Instead, wouldn&amp;#8217;t it be great if you could inherit from a standard RESTful superclass and just configure your controller if it needed.&lt;/p&gt;


	&lt;p&gt;Problem #2: When you have a has_many relationship between two models, and want to nest your routes. e.g. http://yoursite.com/posts/42/comments/3, then you have to change all your links in all your sub-model&amp;#8217;s views.  This is kind of a pain.&lt;/p&gt;


	&lt;p&gt;Solution: resource_controller plugin provides that RESTful superclass and generators to replace all the repetitive code and makes your controllers skinny like models.  Standard models are customizeable through a &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt;-like &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; provided by the plugin.  Generic helper functions for views are also provided so that helper links are generic so you don&amp;#8217;t have the problem of customizing links when making nested routes (is this true?).&lt;/p&gt;


	&lt;p&gt;This tutorial describes how to create blog of postings with a Post model and a Comment model.&lt;/p&gt;


	&lt;p&gt;The Comment model is polymorphic which means that it can be used to place comments not just on the Post model but any other model in the application.&lt;/p&gt;


	&lt;p&gt;Also, the Comment model will be using nested routes.&lt;/p&gt;


	&lt;p&gt;How to install:&lt;/p&gt;


In your rails_root application directory type:
&lt;pre&gt;
svn export http://svn.jamesgolick.com/resource_controller/tags/stable 
  vendor/plugins/resource_controller
&lt;/pre&gt;

	&lt;p&gt;How to use the generator&lt;/p&gt;


&lt;pre&gt;
ruby script/generate scaffold_resource Post title:string body:text
&lt;/pre&gt;

	&lt;p&gt;How to create a polymorphic has_many submodel&lt;/p&gt;


&lt;pre&gt;
ruby script/generate scaffold_resource Comment commentary:references comment:text
&lt;/pre&gt;

	&lt;p&gt;Note: you need to make your own css and application layouts:&lt;/p&gt;


&lt;pre&gt;
public/stylesheets/scaffold.css
app/views/layouts/application.html.erb
&lt;/pre&gt;

	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;CONTROLLERS&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;Now your controllers are skinny:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# /app/controllers/posts_controller.rb
class PostsController &amp;lt; ResourceController::Base
end
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;
/app/controllers/comments_controller.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;
class CommentsController &amp;lt; ResourceController::Base
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;ResourceController::Base inherits from the usual ApplicationController&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;MODELS&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;Now modify your Post model to express the has_many relationship with the Comment model.&lt;/p&gt;


	&lt;p&gt;Ie. A post have many comments.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# /app/models/post.rb 
class Post &amp;lt; ActiveRecord::Base
  has_many :comments, :as =&amp;gt; :commentary
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note: For non-polymorphic relationships you don&amp;#8217;t need :as =&amp;gt; commentary.&lt;/p&gt;


	&lt;p&gt;Modify your Comment model to have the polymorphic belongs_to relationship.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# /app/models/comment.rb 
class Comment &amp;lt; ActiveRecord::Base
  belongs_to :commentary, :polymorphic =&amp;gt; true
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;How polymorphic tables works:
Your comments table has two columns (in addition to the text field that stores your comment): commentary_id and commentary_type.  
commentary_type is the name of the table you want to reference.
commentary_id is the row in the table that you&amp;#8217;re referencing.
In this way you can associate a comment to any row in any table in your database.  You can comment on anything in your application.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;CREATING A POST HAS&lt;/span&gt;_MANY &lt;span class=&quot;caps&quot;&gt;COMMENT RELATIONSHIP&lt;/span&gt;, WHERE &lt;span class=&quot;caps&quot;&gt;COMMENT IS POLYMORPHIC&lt;/span&gt;.&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;MIGRATIONS&lt;/span&gt;
You need to modify your  002_create_comments.rb migration to make it polymorphic.
&lt;pre&gt;&lt;code&gt;
# /db/migrate/002_create_comments.rb
class CreateComments &amp;lt; ActiveRecord::Migration
  def self.up
    create_table :comments, :force =&amp;gt; true do |t|
    t.references :commentary, polymorphic =&amp;gt; true
    t.text :comment

    t.timestamps
    end # do
  end # def self.up

  def self.down
    drop_table :comments
  end
end # class
&lt;/code&gt;&lt;/pre&gt;

Now run your migration.
&lt;pre&gt;&lt;code&gt;
rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

Now you need to add &amp;#8220;belongs_to :post&amp;#8221; to your controller.
This will make it so that you don&amp;#8217;t have to load the parent resource in your controller like this 
&lt;pre&gt;&lt;code&gt;
@post = Post.find(param[:post_id])
&lt;/code&gt;&lt;/pre&gt;

&amp;#8220;belongs_to :post&amp;#8221; will automatically load your parent resource.  This reduces a lot of repetitive coding.
&lt;pre&gt;&lt;code&gt;
# /app/controllers/comments_controller.rb
class CommentsController &amp;lt; ResourceController::Base
  belongs_to :post
end
&lt;/code&gt;&lt;/pre&gt;

Modify your routes.rb file to enable nested routing.
&lt;pre&gt;&lt;code&gt;
# /config/routes.rb file
ActionController::Routing::Routes.draw do |map|
  map.resources :posts, :has_many =&amp;gt; :comments
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;VIEWS&lt;/span&gt;
In your /app/views/comments/_form.html.erb file, take out the commentary field, cuz that&amp;#8217;s not something that is user-facing.  It&amp;#8217;s an internal field used to implement polymorphism.&lt;/p&gt;


Start up your server
&lt;pre&gt;&lt;code&gt;
script/server
&lt;/code&gt;&lt;/pre&gt;

Go to 
&lt;pre&gt;&lt;code&gt;http://localhost:3000/posts/new
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Create dummy data in your database by filling out the form.&lt;/p&gt;


Now, you should be able to add a comment to that posting.  (Assum your posting has an id of 1.)
Go to
&lt;pre&gt;&lt;code&gt;http://localhost:3000/posts/1/comments/new
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Fill out the form.  It should have created a new comment linked to your post record with id 1.&lt;/p&gt;


Check to see if the comment has been associated with your post using the console:
script/console
&lt;pre&gt;&lt;code&gt;
&amp;gt;&amp;gt; Post.find(1)
=&amp;gt; #&amp;lt;Post id: 1, title: &quot;My first post&quot;, body: &quot;restful post&quot;, .......&amp;gt;
&amp;gt;&amp;gt; Post.find(1).comments
=&amp;gt; [#&amp;lt;Comment id: 1, commentary_id: 1, commentary_type: &quot;Post&quot;, comment: &quot;This is a new comment.&quot; ......&amp;gt;]
&amp;gt;&amp;gt; Comment.count
=&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Where is the magic happening?  Let&amp;#8217;s look at the edit comment view.&lt;/p&gt;


	&lt;p&gt;Normally, without using the resource_controller plug, with nested resources, you would have to refer to the parent resource as post_comment_url(@post, @comment).  With resource_controller, all you have to do is use: &amp;#8220;object_url&amp;#8221;.  Ie. in the old way, the helper method names are coupled to the names of your models.  In the new way, the information of the relationships are taken from the controller, and helper method names are independent of the names of the models.  (Coupling is generally bad, because it means your code is brittle and linked dependent on other parts of your code.  Independence is good because it makes your code more modular.)&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# /app/views/comments/edit.html.erb
....
&amp;lt;%= link_to 'Show', object_url %&amp;gt; |
&amp;lt;%= link_to 'Back', collection_url %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;ADDING ANOTHER COMMENTABLE MODEL CALLED&lt;/span&gt; &amp;#8220;ARTICLE&amp;#8221;&lt;/p&gt;


	&lt;p&gt;To see the value of a polymorphism, let&amp;#8217;s create another model called Article and use the same comments table to store comments on articles.
Use the resource_controller generator to create articles:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
ruby script/generate scaffold_resource Article title:string 
 author:string article:text
&lt;/code&gt;&lt;/pre&gt;

Create the database table.
&lt;pre&gt;&lt;code&gt;rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

Configure the models
Add the has_many clause.
&lt;pre&gt;&lt;code&gt;
# /app/models/article.rb
class Article &amp;lt;ActiveRecord::Base
  has_many :comments, :as =&amp;gt; :commentary
end
&lt;/code&gt;&lt;/pre&gt;

Configure the routes.rb file
&lt;pre&gt;&lt;code&gt;
# /config/routes.rb
ActionController::Routing::Routes.draw do |map|
  map.resources :articles, :has_many =&amp;gt; :comments
  map.resources :comments
  map.resources :posts, :has_many =&amp;gt; :comments
end
&lt;/code&gt;&lt;/pre&gt;

Finally, add :article to the belongs_to method call in CommentsController
&lt;pre&gt;&lt;code&gt;
# /app/controllers/comments_controller.rb
class CommentsController &amp;lt; ResourceController::Base
  belongs_to :post, :article
end
&lt;/code&gt;&lt;/pre&gt;

Now it should work.
Let&amp;#8217;s say you already input an article with id of 1.
Then add a comment to your article
&lt;pre&gt;&lt;code&gt;
http://localhost/articles/1/comments/new
&lt;/code&gt;&lt;/pre&gt;

&lt;span class=&quot;caps&quot;&gt;CREATING AN ADMIN NAMESPACE&lt;/span&gt;
Let&amp;#8217;s say you want only the admin to create, edit, or delete Post instances.
Make an admin folder in in /app/controllers and /app/views.
&lt;pre&gt;&lt;code&gt;
mkdir app/controllers/admin
mkdir app/views/admin
mkdir app/views/admin/posts
&lt;/code&gt;&lt;/pre&gt;

Copy your your Post views into /app/views/admin/posts
Note the all the post views still exist in the normal directory location at this point.  They are still accessible publicly at this point.
&lt;pre&gt;&lt;code&gt;
cp app/views/posts/* app/views/admin/posts/
&lt;/code&gt;&lt;/pre&gt;

Copy your post controlelr into /app/controllers/admin
Note: there are going to be 2 copies of the controller, one for the public and one for the admin.  See how we configure each later.
&lt;pre&gt;&lt;code&gt;
cp app/controllers/posts_controller.rb app/controllers/admin
&lt;/code&gt;&lt;/pre&gt;

Modify your posts controller.  Just add &amp;#8220;Admin::&amp;#8221; to the front of your PostsController.
&lt;pre&gt;&lt;code&gt;
# /app/controllers/admin/posts_controller.rb
class Admin::PostsController &amp;lt; ResourceController::Base
end
&lt;/code&gt;&lt;/pre&gt;

To restrict editing ability of posts from the public, delete the following files _form, edit, and new.html.erb in /app/views/posts/.
&lt;pre&gt;&lt;code&gt;
rm app/views/posts/_form.html.erb
rm app/views/posts/new.html.erb
rm app/views/posts/edit.html.erb
&lt;/code&gt;&lt;/pre&gt;

Take out the links to edit functionality in your remaining views: 
app/views/posts/index.html.erb
remove these lines: 
&lt;pre&gt;&lt;code&gt;
&amp;lt;%= link_to 'Edit', object_url(post) %&amp;gt;
&amp;lt;%= link_to 'Destroy', object_url(post), :confirm =&amp;gt; ......... %&amp;gt;
&amp;lt;%= link_to 'New Post', new_object_url %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Remove similar links in the show page:
app/views/posts/show.html.erb&lt;/p&gt;


Configure the public PostsController:
&lt;pre&gt;&lt;code&gt;
# /app/controllers/posts_controller.rb
class PostsController &amp;lt; ResourceController::Base
  actions :all, :except =&amp;gt; [:new, :edit, :create, :update, :destroy]
end
&lt;/code&gt;&lt;/pre&gt;

Create the namespace routes in routes.rb.  Add the following link at the bottom of your routes list in routes.rb
&lt;pre&gt;&lt;code&gt;
# /config/routes.rb
ActionController::Routing::Routes.draw do |map|
...
  map.namespace :admin do |admin|
    admin.resources :posts
  end
end
&lt;/code&gt;&lt;/pre&gt;

If necessary restart your web server.
Now you can access:
&lt;pre&gt;&lt;code&gt;
http://localhost:3000/admin/posts
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note: Your admin section will have access to new, edit, destroy, etc..&lt;/p&gt;


And your public access is here:
&lt;pre&gt;&lt;code&gt;
http://localhost:3000/posts
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;NOW LET&lt;/span&gt;&amp;#8217;S &lt;span class=&quot;caps&quot;&gt;ADD PAGINATION BY CUSTOMIZING THE WAY THE POST CONTROLLER BUILDS COLLECTIONS OF POSTINGS&lt;/span&gt;. A &lt;span class=&quot;caps&quot;&gt;COLLECTION IS A VARIABLE USED WHEN YOU WANT TO DISPLAY A LIST OF ALL YOUR RECORDS&lt;/span&gt;.&lt;/p&gt;


First, install the will_paginate plugin.
By the way, there is a free screencast on will_paginate here:
http://railscasts.com/episodes/51
Here is the command to install the plugin:
&lt;pre&gt;&lt;code&gt;
script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Without customization the PostsController builds collections like this:
@collection = Post.find(:all)
We want to customize this.  Define the collection method to overwrite the way collections are built.
end_of_association_chain is the way resource_controller plugin refers to the name of the model in question.  In this case it will return the Post controller.  If we were in the CommentsController, it would return the Comment model associated with params[:post_id].&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
private
def collection 
  @collection ||= end_of_association_chain.paginate :page =&amp;gt; params[:page], :per_page =&amp;gt; 5
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note: The paginate function comes from the will_paginate controller.&lt;/p&gt;


# /app/views/posts/index.html.erb
# Add pagination links at the bottom.
&lt;pre&gt;&lt;code&gt;
....
&amp;lt;%= will_paginate @posts %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;span class=&quot;caps&quot;&gt;OTHER METHODS FROM RESOURCE&lt;/span&gt;_CONTROLLER
For more documentation and helper methods, take a look at the resource_controller &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt; file:
&lt;pre&gt;&lt;code&gt;
/vendor/plugins/resource_controller/README
&lt;/code&gt;&lt;/pre&gt;
For example,

	&lt;p&gt;To customize the create method.  Place this inside your controller:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
create do
  # Sample customization code and methods:
  flash &quot;Object was created successfully!  Right on!&quot; 
  wants.js {render :template =&amp;gt; &quot;show.rjs&quot;}
  failure.wants.js {render :template =&amp;gt; &quot;display_errors.rjs&quot;}
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;To create a before filter before your controller&amp;#8217;s new method, place this in your controller:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
new_action.before do
  3.times { object.tasks.build } # This is just an example of a customization.
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;To customize the way your controller builds an individual object for the view, overwrite the build_object method.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
private
  def build_object
    @object ||= end_of_association_chain.build_my_object_some_funky_way object_params
  end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If that was your PostsController, then in your posts views you would be able to access your @post variable like normal, but it would be built in the funky way as prescribed by the way you defined build_my_object_some_funky_way method.&lt;/p&gt;


	&lt;p&gt;See the &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt; for many other functions.&lt;/p&gt;</description>
          <pubDate>Mon, 24 Mar 2008 04:59:49 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2008/03/24/resource_controller-plugin/</guid>
          <link>http://davidbeckwith.com/articles/2008/03/24/resource_controller-plugin/</link>
        </item>
    
        <item>
          <title>git, an alternative to SVN </title>
          <description>&lt;p&gt;These are my notes from watching the git peepcode video.  I highly recommend peepcode.com videos. I feel slightly guilty for publishing his notes for his screencast, which costs $9, but I hope this page will ultimately sell more of his screencasts.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;git&amp;#8221; is source control software.  For those of you who are not programmers, source control software is software that tracks changes in your files for several reasons:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;When collaborating on a set of files with a team of people, source control software will prevent you from overwriting somebody else&amp;#8217;s changes to a file.  You must explicitly resolve the conflicts before merging your changes into the repository.&lt;/li&gt;
		&lt;li&gt;It creates a time machine of your code and allows you to literally view the state of all your files in a project at any point in time in the past.  This is helpful if you unwittingly introduced a bug into your code and want to rollback to a state where the bug wasn&amp;#8217;t there.  &lt;/li&gt;
		&lt;li&gt;It can be used to track different branches of development, representing different purposes or levels of stability.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Using source control software is considered to be a best-practice in software engineering.  The current standard open source tool is called &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt; or Subversion.  Subversion is very good, and we use it in the office daily.  git offers a few improvements on subversion, namely&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;response-time / performance (very easy to work locally to make commits fast)&lt;/li&gt;
		&lt;li&gt;agility (easy to make branches and makes you a faster programmer)&lt;/li&gt;
		&lt;li&gt;distributed, so you can synchronize with your laptop, desktop, friend&amp;#8217;s computer, or work computer without having to always connect to a centralized server.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;You can do all of these things with &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt;, but git just makes it a lot easier to.  You can think of git as the &amp;#8220;sqlite3&amp;#8221; of version control software (source control).  Not a huge deal, but if it saves me a few minutes each day, then it&amp;#8217;s worth switching to it.&lt;/p&gt;


	&lt;p&gt;website: git.or.cz&lt;/p&gt;


&lt;h2&gt;Features of git:&lt;/h2&gt;	&lt;p&gt;&lt;ul&gt;
	&lt;li&gt;offline: All files are committed with respect to a local repository.  Therefore, git can always be used offline.  No need for central server or internet.&lt;/li&gt;
		&lt;li&gt;distributed: can share git repository with peers&amp;#8212;not just server.&lt;/li&gt;
		&lt;li&gt;agile branching: branching becomes easier than in &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt;: makes you more agile&lt;/li&gt;
		&lt;li&gt;emphasizes content not files&amp;#8230;. not sure how this helps me though.&lt;/li&gt;
	&lt;/ul&gt;&lt;/p&gt;



	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;INSTALLATION&lt;/span&gt;
Mac:
sudo port install git-core&lt;/p&gt;


	&lt;p&gt;Others:
install from source and compile.&lt;/p&gt;


	&lt;p&gt;Latest:
git clone git://git.kernel.org/pub/scm/git/git.git&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;CONFIGURE&lt;/span&gt;
identify yourself to git: email and your name
git config&amp;#8212;global user.name &amp;#8220;David Beckwith&amp;#8221; 
git config&amp;#8212;global user.email &amp;#8220;dbitsolutions@gmail.com&amp;#8221;&lt;/p&gt;


	&lt;p&gt;To view all users:
git config&amp;#8212;list
OR
cat .gitconfig&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;SET UP ALIASES&lt;/span&gt;
git config&amp;#8212;global alias.co checkout&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;VIEW YOUR CONFIGURATION&lt;/span&gt;
cat .gitconfig&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO IGNORE WHITESPACE&lt;/span&gt; (Ruby is whitespace insensitive)
git config&amp;#8212;global apply.whitespace nowarn&lt;/p&gt;


	&lt;p&gt;Some nice aliases:
gb = git branch
gba = git branch -a
gc = git commit -v
gd = git diff | mate
gl = git pull
gp = git push
gst = git status&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;START USING GIT&lt;/span&gt;:
git init&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO IGNORE SOME FILES MAKE A FILE&lt;/span&gt; (in the root directory) &lt;span class=&quot;caps&quot;&gt;CALLED&lt;/span&gt; .gitignore and add some files to it:
 # comments begin with hash.
*.log
db/schema.rb
db/schema.sql&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SCHEDULE THE ADDITION OF ALL FILES TO THE NEXT COMMIT&lt;/span&gt;:
git add .&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SEE WHAT THE STATUS&lt;/span&gt;:
git status&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO COMMIT&lt;/span&gt;:
git commit -m &amp;#8220;First import&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SEE WHAT HAS BEEN COMMITTED&lt;/span&gt;:
git ls-files&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SCHEDULE DELETION OF A FILE&lt;/span&gt;:
git rm &lt;file name&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO COMMIT ALL CHANGES IN FILES IN THE CURRENT REPOSITORY&lt;/span&gt;:
git commit -a&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SCHEDULE THE ADDITION OF AN INDIVIDUAL FILE TO THE NEXT COMMIT&lt;/span&gt;:
git add &lt;file name&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW THE DIFFERENCE AS YOU COMMIT USE THE&lt;/span&gt; -v &lt;span class=&quot;caps&quot;&gt;OPTION&lt;/span&gt;
git commit -v&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO COMMIT AND TYPE THE MESSAGE ON THE COMMAND LINE USE THE&lt;/span&gt; -m &lt;span class=&quot;caps&quot;&gt;OPTION&lt;/span&gt;
git commit -m &amp;#8220;This is the message describing the commit&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO COMMIT AND GET AUTOMATICALLY ANY CHANGES FROM OTHER PEOPLE USE THE&lt;/span&gt; -a &lt;span class=&quot;caps&quot;&gt;OPTION&lt;/span&gt;
git commit -a&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;THE NORMAL COMMIT COMMAND&lt;/span&gt;:
git commit -a -v&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW A LOG OF YOUR COMMITS&lt;/span&gt;
git log&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW A LOG OF YOUR COMMITS WITH A GRAPH TO SHOW THE EXTENT OF THE CHANGES&lt;/span&gt; 
git log&amp;#8212;stat&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO HAVE PAGINATION WHEN VIEWING THE LOG FILE USE THE&lt;/span&gt; -v &lt;span class=&quot;caps&quot;&gt;OPTION&lt;/span&gt;
git log -v&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VISUALIZE YOUR CHANGES&lt;/span&gt;
gitk&amp;#8212;all&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO CREATE A NEW BRANCH&lt;/span&gt;:
git branch &lt;name of your new branch&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW ALL OF THE EXISTING BRANCHES&lt;/span&gt;
git branch&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW A LIST OF ALL BRANCHES&lt;/span&gt;
git branch -a&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SWITCH TO ANOTHER BRANCH&lt;/span&gt;.  The state of your file system will change after executing this command.
git checkout &lt;name of the branch you want to switch to&gt;
OR 
git co &lt;name of the branch you want to switch to&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO MAKE SURE THAT YOUR NEW BRANCH GETS CHANGES FROM THE MASTER BRANCH&lt;/span&gt; (WHERE &lt;span class=&quot;caps&quot;&gt;EVERYBODY ELSE IS WORKING&lt;/span&gt;) USE &lt;span class=&quot;caps&quot;&gt;THE REBASE COMMAND&lt;/span&gt;:
git rebase master&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;TO MERGE YOUR NEW BRANCH INTO THE MASTER BRANCH&lt;/span&gt;.
	&lt;ol&gt;
	&lt;li&gt;first switch back to the master branch.
git co master&lt;/li&gt;
		&lt;li&gt;check to see what changes you&amp;#8217;re about to merge together, compare the two branches:
git diff master xyz&lt;/li&gt;
		&lt;li&gt;if you&amp;#8217;re in the xyz branch, and want to merge the xyz branch into it.
git merge xyz&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO REVERT YOUR CHANGES&lt;/span&gt; to before the merge.
git reset&amp;#8212;hard &lt;span class=&quot;caps&quot;&gt;ORIG&lt;/span&gt;_HEAD&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO RESOLVE CONFLICTS&lt;/span&gt; just edit your file.  Remove the markings, add the file, then commit.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO CREATE A BRANCH AND SWITCH TO THE BRANCH IN ONE MOVE&lt;/span&gt;:
git checkout -b &lt;name of new branch&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO CREATE A&lt;/span&gt; &amp;#8220;CLIPBOARD&amp;#8221; or &amp;#8220;STASH&amp;#8221; &lt;span class=&quot;caps&quot;&gt;OF CHANGES THAT ARE NOT YET COMMITED&lt;/span&gt; (SO &lt;span class=&quot;caps&quot;&gt;THAT YOU CAN SWITCH TO ANOTHER BRANCH IN THE MIDDLE OF YOUR CHANGES&lt;/span&gt;.), &lt;span class=&quot;caps&quot;&gt;CREATE A STASH&lt;/span&gt;.
git stash &amp;#8220;Put a message here to remind you of what you&amp;#8217;re saving to the clipboard&amp;#8221;&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;TO SWITCH AWAY FROM THE CURRENT BRANCH&lt;/span&gt;
git co &lt;branch you want to switch to&gt;
	&lt;ol&gt;
	&lt;li&gt;do whatever&lt;/li&gt;
		&lt;li&gt;switch back to the stashed branch
git co &lt;the stashed branch&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW THE LIST OF STASHES&lt;/span&gt;
git stash list&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;TO LOAD BACK THE&lt;/span&gt; &amp;#8220;CLIPBOARD&amp;#8221; OR &amp;#8220;STASH&amp;#8221; 
git stash apply
	&lt;ol&gt;
	&lt;li&gt;now you can continue to work where you were previously.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO DELETE A BRANCH THAT IS NOT USED ANYMORE&lt;/span&gt;, but already merged into the current branch.  (TO &lt;span class=&quot;caps&quot;&gt;CLEAN UP&lt;/span&gt;)
git branch -d &lt;name of branch you want to delete&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO DELETE AN UNMERGED BRANCH&lt;/span&gt; 
git branch -D &lt;name of branch you want to delete&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO DELETE THE STASH&lt;/span&gt;.  (ERASE &lt;span class=&quot;caps&quot;&gt;THE&lt;/span&gt; &amp;#8220;CLIPBOARD&amp;#8221; &lt;span class=&quot;caps&quot;&gt;FROM MEMORY&lt;/span&gt;)
git stash clear&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;TO SET UP YOUR REPOSITORY FOR SHARING ON A CENTRAL SERVER&lt;/span&gt;
	&lt;ol&gt;
	&lt;li&gt;Copy up your repository. e.g.:
scp -r my_project deploy@yourbox.com:my_project&lt;/li&gt;
		&lt;li&gt;Move your files on the remote server to /var/git/my_project&lt;/li&gt;
		&lt;li&gt;For security make the owner of this project git&lt;/li&gt;
		&lt;li&gt;On the repository server:
sudo chown -R git:git my_project&lt;/li&gt;
		&lt;li&gt;then (for security) restrict the &amp;#8220;deploy&amp;#8221; user to doing git-related things in /etc/passwd with a git-shell.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO CHECK OUT THE GIT REPOSITORY TO YOUR LOCALHOST&lt;/span&gt;.  &lt;span class=&quot;caps&quot;&gt;ON YOUR LOCAL HOST&lt;/span&gt; do this:
git clone git@yourbox.com:/var/git/my_project&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SEE SOME INFO ABOUT THE REPOSITORY THAT WILL TELL YOU WHICH REPOSITORY IS THE MASTER AND WHICH IS THE SLAVE&lt;/span&gt;:
cat .git/config&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;By virtue of having cloned the remote repository, your local repository becomes the slave and will track and synchronize with the remote master branch.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO UPDATE YOUR LOCAL BRANCH FROM THE REMOTE SERVER&lt;/span&gt;:
git pull&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO GET A COPY OF THE ENTIRE REMOTE REPOSITORY&lt;/span&gt; (e.g. a repository named &amp;#8220;laptop&amp;#8221;) &lt;span class=&quot;caps&quot;&gt;WITHOUT MERGING THEM INTO YOUR LOCAL BRANCHES USE FETCH&lt;/span&gt;
git fetch laptop&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;TO MERGE TWO LOCAL BRANCHES&lt;/span&gt; (ie. your local xyz branch with your local master branch) &lt;span class=&quot;caps&quot;&gt;USE MERGE&lt;/span&gt;
git merge laptop/xyz
	&lt;ol&gt;
	&lt;li&gt;this merged the (already copied laptop repository&amp;#8217;s xyz branch) with the current branch you&amp;#8217;re sitting in.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO MERGE THE REMOTE BRANCH WITH YOUR LOCAL BRANCH THAT YOU ARE SITTING IN USE PULL&lt;/span&gt;&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;TO ADD LOCAL KNOWLEDGE&lt;/span&gt; (TO &lt;span class=&quot;caps&quot;&gt;YOUR LOCAL REPOSITORY&lt;/span&gt;) OF &lt;span class=&quot;caps&quot;&gt;A 2ND REMOTE REPOSITORY&lt;/span&gt;, LIKE &lt;span class=&quot;caps&quot;&gt;YOUR LAPTOP&lt;/span&gt;
git remote add laptop duo2book.local:repos/m_project
	&lt;ol&gt;
	&lt;li&gt;&amp;#8220;laptop&amp;#8221; is the name of the remote repository.  &amp;#8220;duo2book.local&amp;#8221; is the name of the machine, I guess&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO VIEW META INFORMATION ABOUT THAT REMOTE REPOSITORY&lt;/span&gt;
git remote show laptop&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TOP PUSH A COMMITTED LOCAL CHANGE OF THE&lt;/span&gt; xyz &lt;span class=&quot;caps&quot;&gt;BRANCH TO THE REMOTE&lt;/span&gt; laptop &lt;span class=&quot;caps&quot;&gt;BRANCH&lt;/span&gt;
git push laptop xyz&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO CREATE A TRACKING BRANCH&lt;/span&gt; (A &lt;span class=&quot;caps&quot;&gt;SLAVE BRANCH&lt;/span&gt;).  Ie. to link a local branch to a remote branch:
git branch&amp;#8212;track &lt;local name of branch&gt; &lt;remote name of branch&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;NOW IF YOU&lt;/span&gt;&amp;#8217;RE &lt;span class=&quot;caps&quot;&gt;SITTING IN THE LOCAL TRACKING BRANCH&lt;/span&gt;, TO &lt;span class=&quot;caps&quot;&gt;PULL YOU DON&lt;/span&gt;&amp;#8217;T &lt;span class=&quot;caps&quot;&gt;NEED TO SPECIFY THE REMOTE TRACKING BRANCH&lt;/span&gt;:
git  pull&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Note: you can tracking different branches from different remote machines.  For example, you can track your friend&amp;#8217;s &amp;#8220;upgrade&amp;#8221; branch and track the &amp;#8220;master&amp;#8221; branch from your main webserver.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;ol&gt;
	&lt;li&gt;By convention, &amp;#8216;origin&amp;#8217; is the &amp;#8216;centralized server&amp;#8217; which is the way &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt; is usually set up on a remote server.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO SEE WHICH LOCAL BRANCHES ARE TRACKING A REMOTE BRANCH&lt;/span&gt;:
git remote show origin&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO WORK WITH AN SVN REPOSITORY BUT WORK WITH GIT LOCALLY&lt;/span&gt;:
git-svn clone &lt;http location of an svn repository&gt;&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Now you can work with the checked out directory as though it was a git repository.  (cuz it is)&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO PUSH&lt;/span&gt; (COMMIT) &lt;span class=&quot;caps&quot;&gt;CHANGES TO THE REMOTE SERVER&lt;/span&gt;
git-svn dcommit&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TO UPDATE YOUR LOCAL REPOSITORY FROM THE SVN REPOSITORY&lt;/span&gt;
git-svn rebase&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;NOTE&lt;/span&gt;: make sure you have your perl bindings to your local svn installation.&lt;/li&gt;
	&lt;/ol&gt;</description>
          <pubDate>Fri, 21 Mar 2008 18:42:31 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2008/03/21/git-an-alternative-to-svn/</guid>
          <link>http://davidbeckwith.com/articles/2008/03/21/git-an-alternative-to-svn/</link>
        </item>
    
        <item>
          <title>In Praise of the Unpowerful</title>
          <description>&lt;p&gt;The title of today&amp;#8217;s sermon: &amp;#8220;In Praise of the Unpowerful&amp;#8221;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m always amazed at how long it takes and how error-prone the process of creating a data-driven website is when the database schema is so conceptually simple, the business rules are simple, you can come up with a database-model in an hour and a complete site map and access rules in another hour, but then to actually create it, debug it, test it, etc. etc.. it takes months for really smart people to execute it to completion.  What is up with that?  Why is it so much more difficult than making a sign at, say, FastSigns?  I can understand if it takes a day or two, but months . . . . ?&lt;/p&gt;


	&lt;p&gt;We love giving up power, but we&amp;#8217;re in denial of that fact.  Look how many constraints RoR imposes upon the structure of Ruby programs when you make a website, and how people in the Rails community get so excited they start drooling all over themselves about that.  Look at &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;, and how they&amp;#8217;re loving those additional constraints as well.  Look how we gave up more power, by making the default database SQLite instead of MySQL in Rails 2.0.  &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;, the king of the unpowerful, is a huge huge success.  (Think how many pages of &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; have been written or generated.)&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not sure what the best interface is going to be to manipulate directly model abstractions like &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; &amp;#8211; whether we&amp;#8217;re using graphical IDEs or writing &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt; scripts to generate code &amp;#8211; but I just like the idea of language creation as a general problem solving approach. . . .  I have a feeling this direction hasn&amp;#8217;t been explored enough. . . . . especially of course in the direction of less powerful languages.  I&amp;#8217;m thinking that there should some really easy way to create DSLs in general.  Like we need software that supports the creation of DSLs. . . . .Maybe that&amp;#8217;s Ruby, but maybe it&amp;#8217;s more than that.&lt;/p&gt;


	&lt;p&gt;Lately, I&amp;#8217;ve been kind of intrigued by the notion of the &lt;a href=&quot;http://www.w3.org/2001/tag/doc/leastPower.html&quot;&gt;Principle of Least Power&lt;/a&gt; in programming languages.&lt;/p&gt;


	&lt;p&gt;I think our tools are simply &lt;span class=&quot;caps&quot;&gt;WAY TOO POWERFUL&lt;/span&gt; for our own good.  Even Rails is way too fine-grained for most peoples&amp;#8217; good.  Yes, I understand that people need to write Othello games in Javascript sometimes and connect to funky-ass payment gateways with their custom APIs.  But there is a huge class of websites that are doing the same shizzle over and over again.&lt;/p&gt;


	&lt;p&gt;I like the idea of thinking about languages in terms of subsets of power.  Give the least powerful subsets to the dumbest people with the least experience to do the easiest tasks, and the most powerful supersets to the smartest people with the most experience to execute the hardest tasks &amp;#8211; but don&amp;#8217;t make the learning curve humungous for the dumb people &amp;#8211; cuz that defeats the purpose.  (I don&amp;#8217;t mean that they&amp;#8217;re stupid actually, they&amp;#8217;re just lacking knowledge and experience like me.  Just a rhetorical device . . . . to illustrate a point.)  For example, &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; is way too powerful for most professional programmers with 2-3 years of experience.  Have you ever seen maintainable &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; code?  I have once, and it was autogenerated.  Same goes for Rails. . . . . It&amp;#8217;s way too easy even with the directory structure they made for you to write unmaintainable code.  &lt;span class=&quot;caps&quot;&gt;TOO MUCH FREEDOM&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Rails is my current favorite framework, and I still enjoy it a lot.  But, there should be a really dumb easy way to make a website that requires no knowledge, no configuration, no fancy complicated command lines.  It should just be one line of code or one line of code that takes an input file for the schema, and an input file for the permissions. . . . okay and one more for the interface (I know that sounds like &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt;, but I&amp;#8217;m thining of something much higher level than Ruby or Erb).  I shouldn&amp;#8217;t have to be configuring observers and turning on and off switches, configuring mongrel clusters, looking at log files, and debugging my deploy.rb file. Making a simple RoR programming is like sitting in the cockpit of a 747 with 5,000,000 switches staring at you in the face.&lt;/p&gt;


	&lt;p&gt;On the other hand, I like scaffold generators in Rails.  They are essentially creating a high-level declarative language with a command line interface and I think that&amp;#8217;s great, but still it&amp;#8217;s way too complicated.  I should not have to read several thousand page textbooks to deal with the aftermath of having typed that command.  Hmm . . . . . maybe I just need to get more involved with Rails code generators.&lt;/p&gt;


	&lt;p&gt;Sorry, I didn&amp;#8217;t mean to rant. . . . . it&amp;#8217;s 3 a.m. here . . . . .   :)&lt;/p&gt;</description>
          <pubDate>Sun, 03 Feb 2008 19:16:07 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2008/02/03/in-praise-of-the-unpowerful/</guid>
          <link>http://davidbeckwith.com/articles/2008/02/03/in-praise-of-the-unpowerful/</link>
        </item>
    
        <item>
          <title>Why CRUD and REST is important</title>
          <description>&lt;p&gt;For a long time, I didn&amp;#8217;t get what the big deal is about pretty URLs like&lt;/p&gt;


	&lt;p&gt;http://www.example.com/people/1&lt;/p&gt;


	&lt;p&gt;I still don&amp;#8217;t completely get it, but Roy Fielding, who is one of the authors of the original &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; specification, defined &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; in his PhD thesis at the University of Irvine in 2000.  &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm&quot;&gt;Roy Fielding&amp;#8217;s dissertation&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;David Heinemeier Hansson, the creator of Ruby on Rails, says he didn&amp;#8217;t get it either for a long time until he actually started using it.  His talk at RailsConf 2006 explains why pretty URLs are not just pretty URLs.  After listing to his talk, I started to want to learn more about the &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; architectural style.&lt;/p&gt;


	&lt;p&gt;1. &lt;span class=&quot;caps&quot;&gt;CRUD&lt;/span&gt; (create read update delete) is a design philosophy.  If you find that your application code is getting complicated, you&amp;#8217;re probably not done modeling.  Your controllers, for the most part, should only have 7 actions: index, new, create, show, edit, update, and destroy.  Don&amp;#8217;t just model the nouns as classes.  When you start modeling the relationships between the nouns like &amp;#8220;subscriptions&amp;#8221; and &amp;#8220;memberships,&amp;#8221; &lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt; claims that your controllers will start looking like &lt;span class=&quot;caps&quot;&gt;CRUD&lt;/span&gt;, and your code will no longer be handling exotic exceptional cases and complicated business rules.  If your controllers don&amp;#8217;t look like &lt;span class=&quot;caps&quot;&gt;CRUD&lt;/span&gt;, it means that you&amp;#8217;re not done: you haven&amp;#8217;t finished thinking about your model deeply enough.  &lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt; reminds us not to forget to model (make classes for) things like relations, events, and states.&lt;/p&gt;


	&lt;p&gt;2. One of the beneficial side-effects when using ActiveResource (the Rails library supporting &lt;span class=&quot;caps&quot;&gt;CRUD&lt;/span&gt;) is that you can use one controller for many clients and get web services, &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt;, and mobile phone formats with little or no extra programming.&lt;/p&gt;


	&lt;p&gt;3. Another good side-effect is discoverability.  If everybody followed this convention it would be very easy, if not automatic, to discover web services and APIs simply by knowing the name of the thing that you&amp;#8217;re looking for.  People can start using your web service to make more interesting applications that combine different web services.  It&amp;#8217;s kind of like how a &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; script calls many stateless little programs and strings them together to do something really cool.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.scribemedia.org/2006/07/09/dhh/&quot;&gt;David Heinemeier Hansson&amp;#8217;s talk&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://downloads.scribemedia.net/rails2006/worldofresources.pdf&quot;&gt;Download the Power Point slides as a &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; file here.&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;For me, the bottom-line is less code by following conventions.  But, I think the point of &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; is much more than that.  By following this convention and accepting the constraints that &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; puts on the way you create and design your applications, not only do you write less code, but you get emergent properties induced by these constraints.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.dbithosting.com/tutorials/REST/re7_royfielding.pdf&quot;&gt;(Slide 23 of Roy Fielding&amp;#8217;s RailsConf Europe talk)&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I think some of these emergent properties include, 1. layeredness and serendipity (people can create cool stuff from your data if you expose it to them), 2. simplicity (1 &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; per model exposed as &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; &amp;#8230;. that&amp;#8217;s pretty simple.), 3. scalability, 4. cacheability, 5. discoverability, 6. reliability.&lt;/p&gt;


	&lt;p&gt;Fielding&amp;#8217;s dissertation takes a couple of cups of coffee to finish, so here are &lt;a href=&quot;http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage&quot;&gt;some nice &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; tutorials&lt;/a&gt;  for the rest of us.&lt;/p&gt;


	&lt;p&gt;There&amp;#8217;s a lot to be said about &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;, so it&amp;#8217;s best you check out the original thesis and some of the many tutorials referenced here.  Good luck on your path to coming to peace with &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;.  As for me, I&amp;#8217;m going to start writing RESTful rails apps and see where it takes me. . . . .&lt;/p&gt;</description>
          <pubDate>Sun, 28 Oct 2007 19:56:22 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2007/10/28/why-crud-and-rest-is-important/</guid>
          <link>http://davidbeckwith.com/articles/2007/10/28/why-crud-and-rest-is-important/</link>
        </item>
    
        <item>
          <title>Ruby is getting faster</title>
          <description>&lt;p&gt;Since 2001, Yukihiro Matsumoto has been talking about making Ruby faster.  As our Christmas present for 2007, &lt;span class=&quot;caps&quot;&gt;YARV&lt;/span&gt; (Yet Another Ruby Virtual machine) is going to be released as the next core Ruby release 1.9.0.  This will make the new version of Ruby about 2 to 3 times faster than Ruby 1.8.6.  Below is a &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; and memory usage benchmark across about 10 different algorithms:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&amp;#38;lang=yarv&amp;#38;lang2=ruby&quot;&gt;Benchmarking Ruby 1.9.0 compared to Ruby 1.8.6&lt;/a&gt;&lt;/p&gt;</description>
          <pubDate>Sun, 28 Oct 2007 16:55:07 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2007/10/28/ruby-is-getting-faster/</guid>
          <link>http://davidbeckwith.com/articles/2007/10/28/ruby-is-getting-faster/</link>
        </item>
    
        <item>
          <title>A very nice Rails caching-tutorial</title>
          <description>&lt;p&gt;&lt;a href=&quot;http://www.railsenvy.com/2007/2/28/rails-caching-tutorial&quot;&gt;A very nice Rails caching-tutorial&lt;/a&gt;&lt;/p&gt;</description>
          <pubDate>Fri, 19 Oct 2007 03:15:03 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2007/10/19/a-very-nice-rails-caching-tutorial/</guid>
          <link>http://davidbeckwith.com/articles/2007/10/19/a-very-nice-rails-caching-tutorial/</link>
        </item>
    
        <item>
          <title>Getting Ruby, Rails, Capistrano and SVN up and running on Windows XP</title>
          <description>&lt;p&gt;Here are the basic steps of getting up and running with Ruby, rails,
&lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt;, and Capistrano on Windows:&lt;/p&gt;


1. &lt;a href=&quot;http://instantrails.rubyforge.org/wiki/wiki.pl&quot;&gt;Download and install InstantRails&lt;/a&gt;
	&lt;ul&gt;
	&lt;li&gt;Follow the instructions on &amp;#8220;Getting started with InstantRails&amp;#8221;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;a href=&quot;http://instantrails.rubyforge.org/wiki/wiki.pl?Getting_Started&quot;&gt;InstantRails Tutorial&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;2. gem install capistrano&lt;/p&gt;


	&lt;p&gt;3. &lt;a href=&quot;http://www.aptana.com/&quot;&gt;Download Aptana&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;4. &lt;a href=&quot;http://tortoisesvn.tigris.org&quot;&gt;Download TortoiseSVN for Windows XP&lt;/a&gt;&lt;/p&gt;


5. Set your Path variable in Windows XP
	&lt;ul&gt;
	&lt;li&gt;Right click on &amp;#8220;My Computer&amp;#8221; &lt;/li&gt;
		&lt;li&gt;Click on Properties&lt;/li&gt;
		&lt;li&gt;Click on the Advanced Tab&lt;/li&gt;
		&lt;li&gt;Click on Environment Variables&lt;/li&gt;
		&lt;li&gt;In the bottom pane, selecxt the variable Path and click on Edit&lt;/li&gt;
		&lt;li&gt;Separate each directory with a &amp;#8221;;&amp;#8221;, and add the following directories:&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;c:\InstantRails\php;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;c:\InstantRails\ruby\bin;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;c:\InstantRails\mysql\bin;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;c:\InstantRails\apache\bin;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;6. Make a new rails application&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;open a command window and go to c:\InstantRails\rails_apps\&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;type &amp;#8220;rails your_app&amp;#8221; without the double-quotes.  &amp;#8220;your_app&amp;#8221; is the name of your application.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;7. Apply capistrano to your application directory.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;If you&amp;#8217;re using Capistrano 1.&lt;code&gt;*&lt;/code&gt;, then type &amp;#8220;cap&amp;#8212;apply-to your_app&amp;#8221;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;If you&amp;#8217;re using Capistrano 2.&lt;code&gt;*&lt;/code&gt;, then type &amp;#8220;capify your_app&amp;#8221;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;(To find out what version of Capistrano you&amp;#8217;re using, type &amp;#8220;cap&amp;#8212;version&amp;#8221;.&lt;/li&gt;
	&lt;/ul&gt;</description>
          <pubDate>Mon, 23 Jul 2007 22:21:50 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2007/07/23/getting-ruby-rails-capistrano-and-svn-up-and-running-on-windows-xp/</guid>
          <link>http://davidbeckwith.com/articles/2007/07/23/getting-ruby-rails-capistrano-and-svn-up-and-running-on-windows-xp/</link>
        </item>
    
        <item>
          <title>A super high level workflow/application mark-up language</title>
          <description>&lt;p&gt;About a month or two ago, I was gabbling about a mark-up language for web apps with the under-achiever goal of covering the bottom 75%-ile in terms of complexity of &lt;span class=&quot;caps&quot;&gt;CMS&lt;/span&gt; &amp;#38; workflow web app functionality.  This mark-up language would describe the functionality and workflow of an application without seriously considering (for now) any presentation issues.  So, it&amp;#8217;s a functional but ugly web application mark-up language (FBUWAML).  There could be many uses, but the most immediate one that comes to mind for me is super fast prototyping.&lt;/p&gt;


	&lt;p&gt;The goals of this project are&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;To be able to generate web apps in an &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;/HTML-like language that truly stays at the application level / requirements gathering level, and&lt;/li&gt;
		&lt;li&gt;To target web designers rather than programmers&amp;#8212;kinda like the way &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; does.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;An implementation of this &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; standard (ie. a program or script) would do the database configuration &amp;#38; schema generation/destruction/ modification automatically, so that users wouldn&amp;#8217;t have to mess with MySQL, PhpMyAdmin or anything like that at all.&lt;/p&gt;</description>
          <pubDate>Sat, 19 May 2007 16:10:27 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2007/05/19/a-super-high-level-workflowapplication-mark-up-language/</guid>
          <link>http://davidbeckwith.com/articles/2007/05/19/a-super-high-level-workflowapplication-mark-up-language/</link>
        </item>
    
        <item>
          <title>How to organize your controllers in RoR</title>
          <description>&lt;p&gt;Ruby on Rails (RoR) is an &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; framework.  Let&amp;#8217;s think about what &amp;#8220;C&amp;#8221; means.  &amp;#8220;C&amp;#8221; stands for controllers.  The controller layer is where you collect and organize all of your business rules.  That is, business rules and decision making ability generally &lt;span class=&quot;caps&quot;&gt;DOES NOT&lt;/span&gt; leak into your M or V level, but instead these rules are grouped into named controllers.&lt;/p&gt;


	&lt;p&gt;For the purpose of this discussion let&amp;#8217;s say we were trying to build the following application:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;5 module complex work flow system.  (e.g., automobile design aid: module 1 &amp;#8211; spaceframe, module 2 &amp;#8211; drivetrain, module 3 &amp;#8211; aerodynamics, module 4 &amp;#8211; environmentals, module 5 &amp;#8211; controls)&lt;/li&gt;
		&lt;li&gt;Each of these modules are fairly complex and should themselves be implemented as n-step wizards &lt;/li&gt;
		&lt;li&gt;The modules can either be used in sequence to complete an end-to-end design project (XYZ Concept Car), or they can be used independently to assist in the design of a single subsystem or multiple independent subsystems.  i.e., a project can encompass one or more modules&lt;/li&gt;
		&lt;li&gt;Some modules will produce data that other modules can use to complete their particular function (for example: controls module needs to know about drive train and environmentals)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;What&amp;#8217;s the best way to organize the controllers in such an application?&lt;/p&gt;</description>
          <pubDate>Sat, 19 May 2007 15:55:37 GMT</pubDate>
          <guid>http://davidbeckwith.com/articles/2007/05/19/how-to-organize-your-controllers-in-ror/</guid>
          <link>http://davidbeckwith.com/articles/2007/05/19/how-to-organize-your-controllers-in-ror/</link>
        </item>
    
    
  </channel>
</rss>

