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

<channel>
	<title>Project Entropy</title>
	<atom:link href="http://darynholmes.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://darynholmes.wordpress.com</link>
	<description></description>
	<lastBuildDate>Thu, 23 Oct 2008 08:36:13 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='darynholmes.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/b07175574293609750df605e63528454?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Project Entropy</title>
		<link>http://darynholmes.wordpress.com</link>
	</image>
			<item>
		<title>Zuhlke &#8211; Corporate Networking Event</title>
		<link>http://darynholmes.wordpress.com/2008/10/22/zuhlke-corporate-networking-event/</link>
		<comments>http://darynholmes.wordpress.com/2008/10/22/zuhlke-corporate-networking-event/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 15:53:18 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Corporate Networking]]></category>
		<category><![CDATA[Zuhlke]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=117</guid>
		<description><![CDATA[Zuhlke Engineering is hosting a corporate networking event at Canada Square on the 20th November. There will be an informative one hour presentation, followed by lunch and a networking session.
Here is a short snippet from the leaflet:
Zuhlke will share thier experience in successfully helping CIO’s and Programme / Project Managers in Top Tier Banks and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=117&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.zuehlke.com/en/know-how/nach-technologien/agile-software-entwicklung/" target="_blank">Zuhlke Engineering</a> is hosting a corporate networking event at Canada Square on the 20th November. There will be an informative one hour presentation, followed by lunch and a networking session.</p>
<p>Here is a short snippet from the leaflet:<br />
Zuhlke will share thier experience in successfully helping CIO’s and Programme / Project Managers in Top Tier Banks and other Corporates to:</p>
<ul>
<li>Get the business on your side by capturing requirements in their language but with the precision you need</li>
<li>Win the battle for budgets, ensuring the right level of project funding throughout</li>
<li>Get compliance and audit without the pain</li>
<li>Corner suppliers into delivering only high quality software</li>
</ul>
<p>The speakers at the event are:<br />
<strong>Prof. Dr. Wolfgang Emmerich </strong>(Chairman, Zuhlke UK)<br />
Wolfgang is a Partner in the Zuhlke Technology Group of Switzerland. He was also co-founder of Zuhlke Engineering GmbH, Germany in 1998 and Zuhlke Engineering Ltd, London in 2001, where he is currently Chairman and part-time Principal Consultant, primarily to the investment banking sector.</p>
<p><strong>Keith Braithwaite</strong> (Head of Zuhlke’s Centre for Agile Practice)<br />
Keith is a Principal Consultant and Business Unit Leader with Zuhlke in the UK. He has trained, coached and managed development teams from New York to Sydney working on systems ranging from mobile telephone applications to enterprise scale financial systems. He is a regular presenter at conferences around the world.</p>
<p>This is a free event and seats are limited. If you would like to attend this event then please contact me.</p>
<p>Regards, Daryn</p>
Posted in General, Presentations Tagged: Corporate Networking, Presentations, Zuhlke <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/117/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=117&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/10/22/zuhlke-corporate-networking-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Ajax Fundamentals &#8211; Part 4</title>
		<link>http://darynholmes.wordpress.com/2008/09/23/ajax-fundamentals-part-4/</link>
		<comments>http://darynholmes.wordpress.com/2008/09/23/ajax-fundamentals-part-4/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 17:14:27 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Technologies]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=99</guid>
		<description><![CDATA[Index &#124; Part 1 &#124; Part 2 &#124; Part 3 &#124; Part 4 &#124; Part 5

5. Development and Debugging Tools
5.1. Documenting JavaScript
JSDoc is an open source tool used to add inline documentation to JavaScript source files.   JSDoc is based on the javadoc tool.   Many of the javadoc characteristics have been included in JSDoc.   An example [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=99&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="right"><a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-about-index/">Index</a> | <a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-part-1/">Part 1</a> | <a href="http://darynholmes.wordpress.com/2008/04/03/ajax-fundamentals-part-2/" target="_self">Part 2</a> | <a href="http://darynholmes.wordpress.com/2008/07/12/ajax-fundamentals-part-3/">Part 3</a><span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> </span>Part 4<span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> Part 5</span></p>
<p align="right">
<h2>5. Development and Debugging Tools</h2>
<h3>5.1. Documenting JavaScript</h3>
<p><a href="http://jsdoc.sourceforge.net/" target="_blank">JSDoc</a> is an open source tool used to add inline documentation to JavaScript source files.   JSDoc is based on the javadoc tool.   Many of the javadoc characteristics have been included in JSDoc.   An example of using JSDoc can be found <a href="http://jsdoc.sourceforge.net/#usage" target="_blank">here</a>.</p>
<h3>5.2. Firefox Tools &amp; Extensions</h3>
<p><a href="http://www.mozilla.org/projects/inspector/" target="_blank">DOM Inspector</a> is included in the Mozilla Suite and Firefox browser.   This tool provides a graphical user interface that enables a user to brows the document object model of any site.   One can view, update and insert DOM attributes dynamically.   In order to assist JavaScript developers, DOM Inspector can be switched to JavaScript Object mode.   This shows all the properties and methods available to a JavaScript for a particular mode.   DOM Inspector provides a JavaScript evaluation window that allows the user to execute JavaScript against selected nodes.   There is the option to use CSS Style Rules and Computed Style information.   This allows a user to examine the CSS attributes associated with different page elements.</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/1815" target="_blank">Firefox JavaScript Console</a> is a tool that logs JavaScript errors found on a page when the page is rendered.   The Firefox JavaScript Console gives ‘compiler-type’ messages.   It describes the error that occurred and the gives the line number.</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/1843" target="_blank">Firebug</a> integrates with Firefox and provides many development tools.   Firebug has a version of a DOM inspector that enables a developer to find elements.   CSS support allows settings to be altered and viewed.   Firebug allows one to monitor the network activity in order to determine how long it takes for different sections of a page to download.      A JavaScript Debugger allows one to debug and step through the JavaScript at runtime.</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/249/" target="_blank">HTML Validator</a> is a Mozilla extension that performs HTML validation within Firefox and Mozilla.   HTML Validator validates the HTML locally and does not use a remote third party.   The number of errors of a HTML page is seen on the form of an icon in the status bar when browsing.   HTML Validator offers a set of tools to assist in validating and correcting HTML tags.</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/165" target="_blank">Checky</a> is Firefox extension tool for validating HTML.   In addition to HTML, Checky can validate XHTML, CSS, RDF, RSS, XML and many more formats.   Checky sends the source to third-party cites to be validated.   The third-party cites may be free or commercial services.</p>
<p><a href="http://chrispederick.com/work/web-developer/">Pederick’s Firefox Web Developer</a> extension offers a large set of tools for a website developer.      Web Developer provides an extensive set of tools, from highlighting table cells to converting ‘GET’ requests to ‘POST’ requests.   This toolbar contains more than 80 tools and is an essential commodity.</p>
<h3>5.3. JavaScript Syntax Checking</h3>
<p><a href="http://www.jslint.com/" target="_blank">JSLint</a> is an online tool that evaluates JavaScript code.   JSLint scans the JavaScript code and identifies syntax errors, structural problems and questionable coding-style conventions.</p>
<h3>5.4. Compression and Obfuscation</h3>
<p><a href="http://hometown.aol.de/_ht_a/memtronic/" target="_blank">MemTronic&#8217;s</a> FREEWARE HTML/JavaScript Cruncher-Compressor  is a freeware tool that can perform both compression and obfuscation.   The MemTronic&#8217;s website provides the following information.   The tool can Crunch, Compress and Obfuscate.   Crunching removes all comments and whitespace.   Crunching has a bandwidth saving between 20%-50%.   Compressing will compress the script with a real compression-scheme, with auto decompression added to the file.   This results in bandwidth savings between 40% &#8211; 90%.   The obfuscator has not been released at this stage.   Once complete this tool will encode the script into a format that humans can not easily read.   When using Compress, the file will undergo a level of obfuscation.</p>
<p align="right"><a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-about-index/">Index</a> | <a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-part-1/">Part 1</a> | <a href="http://darynholmes.wordpress.com/2008/04/03/ajax-fundamentals-part-2/" target="_self">Part 2</a> | <a href="http://darynholmes.wordpress.com/2008/07/12/ajax-fundamentals-part-3/">Part 3</a><span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> </span>Part 4<span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> Part 5</span></p>
<p align="right">
Posted in AJAX, Technologies Tagged: AJAX, JavaScript, Tools <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/99/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=99&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/09/23/ajax-fundamentals-part-4/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Ajax Fundamentals &#8211; Part 3</title>
		<link>http://darynholmes.wordpress.com/2008/07/12/ajax-fundamentals-part-3/</link>
		<comments>http://darynholmes.wordpress.com/2008/07/12/ajax-fundamentals-part-3/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 08:39:01 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Search Engine Indexing]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=86</guid>
		<description><![CDATA[Index &#124; Part 1 &#124; Part 2 &#124; Part 3 &#124; Part 4 &#124; Part 5
3. Security Issues
The XMLHttpRequest object is restricted to run within the browser’s security sandbox. Any resources requested by the XMLHttpRequest object must reside within the same domain from which the calling script originated. Therefore the XMLHttpRequest object is constrained to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=86&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="right"><a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-about-index/">Index</a> | <a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-part-1/">Part 1</a> | <a href="http://darynholmes.wordpress.com/2008/04/03/ajax-fundamentals-part-2/" target="_self">Part 2</a> | Part 3<span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> </span><a href="http://darynholmes.wordpress.com/2008/09/23/ajax-fundamentals-part-4/" target="_self">Part 4</a><span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> Part 5</span></p>
<h2>3. Security Issues</h2>
<p>The XMLHttpRequest object is restricted to run within the browser’s security sandbox. Any resources requested by the XMLHttpRequest object must reside within the same domain from which the calling script originated. Therefore the XMLHttpRequest object is constrained to requesting resources that reside within the same domain from which the script was originally served. The W3C <a href="http://www.w3.org/TR/XMLHttpRequest/" target="_blank">states</a>, that in the future The XMLHttpRequest Object specification will define a way of doing cross-site requests.</p>
<p>There is an overabundance of online documentation stating that Ajax introduces multiple security threats. These threats include fake requests, denial of service, cross-site scripting (XSS), reliance on client-side security, and more. Jeremiah Grossman’s article, <a href="http://jeremiahgrossman.blogspot.com/2006/11/myth-busting-ajax-in-security.html" target="_blank">Myth-Busting AJAX (In)security</a>, maintains that these security issues existed before Ajax and the recommended security best practices remain unchanged. Part of internet security basics is to distrust the client. Ajax is a client side technology and requests need to be treaded with the same caution as all other calls.</p>
<h2>4. Disadvantages</h2>
<h3>4.1. Usability Problems</h3>
<p>Web users have become familiar with using classic web pages. Users have become accustomed to using browser features such as the back and next buttons. Ajax calls are not loaded onto the browsers navigation stack. Therefore the back button will not undo the last ‘Ajax operation’. Developers need to explicitly cater for undo operations.</p>
<p>Ajax enabled pages have a notion of state; this state is altered as the user navigates through the site. The browser is unaware of this state, and it is not reflected in the address bar. Therefore users are not always able to book mark a certain page state. Developers need to consider this when deciding on when to use Ajax.</p>
<p>The asynchronous nature may make page updates difficult for the user to notice. The developer needs a way of drawing the user’s attention to the modified section of the page. The ‘yellow-fade technique’ has become common practice. In this technique the changes are highlighted with a yellow background, and the yellow fades gradually. These and other techniques are becoming familiar to web users.</p>
<h3>4.2. JavaScript Disabled</h3>
<p>If a user has disabled JavaScript no JavaScript will be executed and certainly no Ajax requests will be sent. A site that relies too heavily on JavaScript will be crippled if the user disables JavaScript, <a href="http://www.gucci.com/">Gucci</a> is an example of this. This site used to show a blank white page if a user browsed to it after disabling JavaScript. Now it explains that you need to have JavaScript enabled to use the site.</p>
<p>A site that relies on JavaScript for core functionality restricts its users to those who have JavaScript enabled. Having said that we should look at how many users are allowing JavaScript to run in there browsers. The following statistics from <a href="http://www.thecounter.com/">The Counter</a> show JavaScript statistics.</p>
<p><span id="more-86"></span></p>
<p><span style="text-decoration:underline;">Wed Mar 1 00:01:01 2000 &#8211; Fri Mar 17 23:59:01 2000</span><br />
Javascript 1.2+:     260153365     (79%)<br />
Javascript &lt;1.2:     7790575     (2%)<br />
Javascript false:     59884983     (18%)</p>
<p><span style="text-decoration:underline;">Thu Mar 1 00:01:01 2007 &#8211; Thu Mar 22 13:58:01 2007</span><br />
Javascript 1.2+:     56607094     (95%)<br />
Javascript &lt;1.2:     193622     (0%)<br />
Javascript false:     2524217     (4%)</p>
<p>These stats show that most users are using JavaScript, therefore many stake holders would approve of the use of Ajax on their sites. Although there are cases where limiting access is unacceptable.</p>
<h3>4.3. Search Engine Indexing</h3>
<p>Web crawlers automatically navigate through the web by following link tags e.g. href, src etc. Current web crawlers do not examine client side scripts. Search engines skip the JavaScript code that executes the Ajax calls. Content loaded by Ajax calls will not be indexed by search engines.</p>
<p>Multiple solutions have been proposed to solve this problem. Most of these are workarounds and do not solve the underlying problem. In fact some approaches are considered as <a href="http://www.softwaredeveloper.com/features/google-ajax-play-nice-061907/" target="_blank">cloaking</a> and can get the site black listed by Google. Google have stated that they will improve there searches, at present they do not follow Ajax calls. In order to make sure that specific content will be found by search engines, the site should have standard HTML links that web crawlers can follow.</p>
<p align="right"><a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-about-index/">Index</a> | <a href="http://darynholmes.wordpress.com/2008/04/02/ajax-fundamentals-part-1/">Part 1</a> | <a href="http://darynholmes.wordpress.com/2008/04/03/ajax-fundamentals-part-2/" target="_self">Part 2</a> | Part 3<span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> </span><a href="http://darynholmes.wordpress.com/2008/09/23/ajax-fundamentals-part-4/" target="_self">Part 4</a><span style="color:#c0c0c0;"> <span style="color:#000000;">|</span> Part 5</span></p>
<p align="right"><span style="color:#c0c0c0;"></span></p>
<p align="right">
<p align="right">
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/86/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/86/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/86/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/86/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/86/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/86/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/86/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/86/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/86/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/86/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/86/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/86/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=86&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/07/12/ajax-fundamentals-part-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Thinking in Rails – Part 1</title>
		<link>http://darynholmes.wordpress.com/2008/07/10/private-thinking-in-rails-%e2%80%93-part-1/</link>
		<comments>http://darynholmes.wordpress.com/2008/07/10/private-thinking-in-rails-%e2%80%93-part-1/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 15:55:50 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=79</guid>
		<description><![CDATA[Part 0
In this part we look at the basic set of requirements for our text editor. I have no doubt that these requirements will change, but let’s have a quick look to get an idea of the direction we are heading in.
Text Editor Requirements
As mentioned in part 0, the text editor is going to be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=79&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://darynholmes.wordpress.com/2008/07/10/thinking-in-rails-%E2%80%93-part-0/" target="_self">Part 0</a></p>
<p>In this part we look at the basic set of requirements for our text editor. I have no doubt that these requirements will change, but let’s have a quick look to get an idea of the direction we are heading in.</p>
<h2>Text Editor Requirements</h2>
<p>As mentioned in part 0, the text editor is going to be a very basic editor. It will maintain a version history that will allow users to roll back to a previous version of a document. This requirement is what will make this task interesting and worthwhile.</p>
<p>We would like to end up with screens similar to this:</p>
<p>The documents index page:</p>
<p><a href="http://darynholmes.files.wordpress.com/2008/07/document-index.png"><img class="alignnone size-full wp-image-82" src="http://darynholmes.files.wordpress.com/2008/07/document-index.png?w=439&#038;h=175" alt="" width="439" height="175" /></a></p>
<p><span id="more-79"></span></p>
<p>Clicking ‘show’ will show the related document and give the user an option to edit it.</p>
<p>Clicking ‘edit’ will show a form that allows the user to edit the document. When the user clicks ‘save’, the application creates a new version, without overwriting existing versions.<br />
<em>We will be providing this behaviour with a slight ‘twist of hand’. I will come back to this point when we actually implement it.</em></p>
<p>Clicking ‘delete’ will completely remove the document and all its versions – this is not a roll back.</p>
<p>If the user clicks on ‘History’ on ‘Second one’. We expect to see a screen similar to this:</p>
<p><a href="http://darynholmes.files.wordpress.com/2008/07/show-document-2.png"><img class="alignnone size-full wp-image-85" src="http://darynholmes.files.wordpress.com/2008/07/show-document-2.png?w=398&#038;h=212" alt="" width="398" height="212" /></a></p>
<p>Clicking ‘show’ will show the relevant version.<br />
Clicking ‘rollback’ will delete the latest version, thus rolling back to the previous version – this is deleting one version only, not the entire document.</p>
<h3>What is next?</h3>
<p>Next we will have a quick look at the database schema and then we finally move onto Rails code! We will not be using the scaffolding features of Ruby on Rails. We will create our application from the ground up – generating models, controllers and views independently. We will also be coding using TDD. If you are new to Rails, I am sure you will enjoy the upcoming posts.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/79/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/79/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=79&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/07/10/private-thinking-in-rails-%e2%80%93-part-1/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>

		<media:content url="http://darynholmes.files.wordpress.com/2008/07/document-index.png" medium="image" />

		<media:content url="http://darynholmes.files.wordpress.com/2008/07/show-document-2.png" medium="image" />
	</item>
		<item>
		<title>Thinking in Rails – Part 0</title>
		<link>http://darynholmes.wordpress.com/2008/07/10/thinking-in-rails-%e2%80%93-part-0/</link>
		<comments>http://darynholmes.wordpress.com/2008/07/10/thinking-in-rails-%e2%80%93-part-0/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 15:37:06 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=77</guid>
		<description><![CDATA[Part 1
This is ‘part 0’ as it is an explanation of the tutorial, no Rails code is covered in this part &#8211; I still need to write the code. This post explains what you can expect to see in future parts of this tutorial. If there is a topic you would like me to cover [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=77&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:right;"><a href="http://darynholmes.wordpress.com/2008/07/10/private-thinking-in-rails-%E2%80%93-part-1/" target="_self">Part 1</a></p>
<p>This is ‘part 0’ as it is an explanation of the tutorial, no Rails code is covered in this part &#8211; <em>I still need to write the code</em>. This post explains what you can expect to see in future parts of this tutorial. If there is a topic you would like me to cover then please feel free to make a request…</p>
<h3>What is the purpose of this tutorial?</h3>
<p>Ruby is not just another OOP language. It has many idioms and constructs which seem foreign at first. Once a developer becomes familiar with these aspects the developer tends to program in a new way – the once foreign code starts to feel very natural.</p>
<p>Moving from Java or .Net to Ruby (and Ruby on Rails) is a challenge, but it is worth the effort. Once you start thinking in the Ruby and Rails way code starts falling into place. To cross the conceptual chasm you need to read many articles, books and as much code as you can. This tutorial aims to assist you as you crossover. Use it as a stepping stone on your path to the land of the <a href="http://en.wikipedia.org/wiki/Duck_typing" target="_blank">ducks</a>.</p>
<h3>How did this tutorial come to be?</h3>
<p>This tutorial is a spin-off from the ‘Routing in Rails’ tutorial. The ‘text editor’ application covered here was originally intended to be the practical section of <a href="http://darynholmes.wordpress.com/2008/07/06/beginners-tutorial-routing-in-rails-20-with-rest-part-6-of-n/" target="_blank">part 6</a>. I started developing the application and soon realised that the actual routing work was very small, and was being lost amongst the rest of the code. I felt that the application still covered many useful topics, therefore I decided to move it into its own tutorial – and here it is.</p>
<p><span id="more-77"></span></p>
<h3>What does this tutorial cover?</h3>
<p>This tutorial attempts to answer two questions posted to me in previous comments and emails. One question was with regards to one to many relationships and nested resources. This was covered in part 6 of the ‘Routing Tutorial’ – here we use them to build the ‘text application’ below.</p>
<p>The second question was from Tom made here: “When you get to RESTful routing I would like to see an example of how to add a Save As function. This would allow the user to derive a new record in a table from an existing record. So it would start as an edit function but end as a create action instead of an update action”</p>
<p><em>The second question poses an interesting REST problem. Some readers may not agree with the solution I am suggesting here. If you have any objections to this solution, please voice your objection in a comment, this will help all of us.</em></p>
<p>In addition to answering these questions, this tutorial will cover some common Rails problems e.g. using 2 models with 1 form, has many function, YAML, testing in Rails, replacing link_to with button_to etc.</p>
<p>As you can see, this tutorial covers many topics. I do not intend to cover each topic in detail &#8211; <em>I would like to, I just don’t have the time</em>. The ‘Rails Routing Tutorial’ focused on one specific topic. This tutorial shows you a bigger picture; the aim is to help you to start thinking in Rails.</p>
<h3>What is not covered in this tutorial?</h3>
<p>We will not be creating the definitive Rails application. The application being developed here should be thought of as the output of iteration one. While following along you should find yourself thinking: ‘would it not be better to do this?’, ‘if we did this, the test would be much cleaner’, ‘I wonder if we can add this information to the view’. If you start thinking like that, then you are starting to think in the Rails way.</p>
<p>Even though it is a good idea to add CSS to your Rails application from a very early stage, I do not intend to cover CSS. I would rather focus on other topics, at least for the first few parts of this tutorial – <em>I may include it at a later stage</em>.</p>
<p>This tutorial will cover the default Rails testing and not RSpec. RSpec is good and I recommend that you look into it. The only reason I am not using it here is because it requires plug-ins. These plug-ins are version dependant and I would rather avoid the potential versioning conflicts that may result from this. The testing lessons learned here can be carried over to RSpec.</p>
<h3>What about the Music Store?</h3>
<p>In this tutorial we will not be using the <em>amazing</em> Music Store application from the Routing tutorial. Instead we can create a new application. This new application will be a plain text editor. The text editor will have a version history. This will allow a user to ‘roll back’ to a previous version of the document.</p>
<p>This will be a basic text editor. The intension is not to create a fully fledged text editor. The aim is to familiarise ourselves with the Rails development process so that we begin to think in Rails.</p>
<h3>What is next?</h3>
<p>Next we look at the basic set of requirements of the text editor application. Please let me know if you would like to know more about a specific Rails topic, I will try to work it into the tutorial.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/77/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/77/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/77/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=77&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/07/10/thinking-in-rails-%e2%80%93-part-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Short-listed!?!</title>
		<link>http://darynholmes.wordpress.com/2008/07/08/short-listed/</link>
		<comments>http://darynholmes.wordpress.com/2008/07/08/short-listed/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 21:17:25 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[blog awards]]></category>
		<category><![CDATA[computer weekly]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=75</guid>
		<description><![CDATA[About a week ago I noticed some incoming links from Computer Weekly.com. I assumed that someone had commented on one of my posts, so I browsed there wondering if it was a positive or negative comment. Once the page loaded, I was completely surprised. It turns out that this blog has been short-listed for the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=75&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>About a week ago I noticed some incoming links from Computer Weekly.com. I assumed that someone had commented on one of my posts, so I browsed there wondering if it was a positive or negative comment. Once the page loaded, I was completely surprised. It turns out that this blog has been short-listed for the <a href="http://www.computerweekly.com/Articles/2008/06/30/230439/programming-and-development-blogs-computerweekly.com-it-blog-awards.htm" target="_blank">Computer Weekly.com IT Blog Awards</a>! This came as a complete surprise to me.</p>
<p>This blog had really humble beginnings. In fact it was not even my idea to start a blog, it was my <a href="http://www.zuehlke.com/en/know-how/nach-technologien/agile-software-entwicklung/" target="_blank">work</a> that encouraged me to start one. Initially I felt that I did not have that much to contribute to the world at large. In fact I still don&#8217;t feel that my blog is as innovative as some others, although judging by the response to my &#8216;<a href="http://darynholmes.wordpress.com/2008/03/15/beginners-tutorial-routing-in-rails-20-with-rest-part-1-of-n/" target="_blank">Routing In Rails Tutorial</a>&#8216; it appears as if I do have a nice way of explaining things. I guess this is one of the main reasons I have been voted onto the shortlist.</p>
<p>The competition ends on the 31st of July 2008. If you would like to vote please go to this <a href="http://www.computerweekly.com/blogawards.htm" target="_blank">on-line voting page</a>. This blog can be found under the &#8216;Programming and technical blogs&#8217;<strong> </strong>drop-down list. It is a surprisingly painless exercise, it takes less then a minute and no registration is required.</p>
<p>Thank you to all of you who have voted for this blog.</p>
<p>Daryn</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/75/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/75/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/75/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=75&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/07/08/short-listed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Beginners Tutorial: Routing in Rails 2.0 (with REST) &#8211; Part 6 of n</title>
		<link>http://darynholmes.wordpress.com/2008/07/06/beginners-tutorial-routing-in-rails-20-with-rest-part-6-of-n/</link>
		<comments>http://darynholmes.wordpress.com/2008/07/06/beginners-tutorial-routing-in-rails-20-with-rest-part-6-of-n/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 20:33:00 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Routing]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=73</guid>
		<description><![CDATA[In part 5 we looked at RESTful routing. In this part we continue to explore RESTful routing, by examining nested resources.
I originally planned to cover nested routes and to cover two questions posted to me in previous comments and emails. One question was with regards to &#8216;one to many relationships&#8217; e.g. an album has many [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=73&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In <a href="http://darynholmes.wordpress.com/2008/05/26/beginners-tutorial-routing-in-rails-20-with-rest-part-5-of-n/">part 5</a> we looked at RESTful routing. In this part we continue to explore RESTful routing, by examining nested resources.</p>
<p>I originally planned to cover nested routes and to cover two questions posted to me in previous comments and emails. One question was with regards to &#8216;one to many relationships&#8217; e.g. an album has many songs. The second question was from Tom in part 3; this was about adding save as functionality.</p>
<p>In trying to answer these questions I created a new application – a text editor with a version history. This has turned out to be a fairly interesting piece of work. I then changed my mind and decided to include it in a follow up post. I am hoping to have that out later this week (before Friday the 11th of July).  As the ‘follow up’ post will have a practical example of nested resources, this post will not have the usual practical section with the experiments.</p>
<h2>Part 6</h2>
<h3>Introduction to Nested Resources</h3>
<h4>The Nested URI</h4>
<p>Returning to the familiar Music Store application, imagine we added songs to the application. Like Albums, Songs are resources and we could expect to access a song with this URI:</p>
<p>/songs/124</p>
<p>We could then perform the required CRUD operations on that URI based on the REST API as discussed in part 5.</p>
<p>An album has many songs. We can express this within the URI e.g.</p>
<p>/albums/10/songs/124</p>
<p>Once again we could make use of the HTTP verbs to perform CRUD in a RESTful way.</p>
<p><strong>In this particular implementation</strong>, this URI does not mean that this is the <!--[if gte mso 9]&gt; Normal   0   21         false   false   false                             MicrosoftInternetExplorer4 &lt;![endif]--><!--[if gte mso 9]&gt; &lt;![endif]--><!--  --><!--[if gte mso 10]&gt; &lt;!   /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} --> <!--[endif]-->124<sup>th</sup> song of album 10 -<em> it is possible for it to be the fist song of album 10</em>.  The URI is pointing to the 124<sup>th</sup> song in the system.</p>
<p>If we wanted the URI to state the song\track number of the specified album then we could alter the above implementation. Then we could expect to see URIs of:</p>
<p>/albums/10/songs/5<br />
and<br />
/albums/11/songs/5</p>
<p>This would not result in a URI conflict.</p>
<p><span id="more-73"></span></p>
<h3>Implementing Nested resources in Rails</h3>
<p>If we decided to add songs to the Music Store application, we could start off by aiming for a URI of:</p>
<p>/songs/124</p>
<p>As you may recall, we can achieve this by declaring this resource in the routes.rb file:</p>
<pre class="brush: ruby;">
map.resources :songs
</pre>
<p>This will give us access to helper methods such as songs_url, song_url (@song) etc. This was discussed in part 5 under ‘Experiment 5.2 Showing the Index Page’.</p>
<p>Next we could aim for a nested URI:</p>
<p>/albums/10/songs/124</p>
<p>To achieve this we use the following construct:</p>
<pre class="brush: ruby;">
  map.resources :albums do |albums|
    albums.resources :songs
  end
</pre>
<p>Note that it is <span style="text-decoration:underline;">albums</span>.resources :songs and not <span style="text-decoration:underline;">map</span>.resources.</p>
<p>With this routing rule, Rails will generate slightly different helper methods. To view these routes we could use the method described in part one. There is also a more convenient rake task: <strong>rake routes</strong>.<br />
<em>This is one of the ‘things’ I have been meaning to mention. You may have read it in a previous comment.</em></p>
<p>If you use ‘rake routes’ you will notice that there are a quite a lot helper methods being generated, more than the 7 I pointed out in part 5. The ‘extra’ methods are there to create URIs for different formats.<em><br />
</em><br />
Below is filtered output from ‘rake routes’</p>
<pre style="border:1px solid black;overflow:auto;width:98%;height:160px;"> album_songs 		GET    	/albums/:album_id/songs	            {:action=&gt;"index", :controller=&gt;"songs"}
 			POST 	/albums/:album_id/songs             {:action=&gt;"create", :controller=&gt;"songs"}
 new_album_song	 	GET   	/albums/:album_id/songs/new         {:action=&gt;"new", :controller=&gt;"songs"}
 edit_album_song	GET    	/albums/:album_id/songs/:id/edit    {:action=&gt;"edit", :controller=&gt;"songs"}
 album_song 		GET    	/albums/:album_id/songs/:id         {:action=&gt;"show", :controller=&gt;"songs"}
 			PUT    	/albums/:album_id/songs/:id         {:action=&gt;"update", :controller=&gt;"songs"}
 			DELETE 	/albums/:album_id/songs/:id         {:action=&gt;"destroy", :controller=&gt;"songs"}</pre>
<p>As you can see, we now have helper methods which look like album_songs_url and album_song_url(@song). The path versions are also available.</p>
<p>Inside the view we could have:<br />
link_to &#8216;Edit&#8217;, edit_album_song(@album, @song)</p>
<p>Looking at the rake routes output above, we can see that the songs controller can get access to the album ID via params[:album_id]. The song ID can be obtained using params[:id].</p>
<p>Now we have helper methods that generate URIs of the form:</p>
<p>/albums/10/songs/124</p>
<p>Our routing system also knows how to deal with incoming URIs of that form.<br />
Now we would like an implementation that allows us to use URIs like:</p>
<p>/albums/10/songs/5</p>
<p>Where song 5 really is the 5th song in album 10. Therefore we could have:</p>
<p>/albums/10/songs/5<br />
and<br />
/albums/20/songs/5</p>
<p>As with most things, it is easy once you know how. To achieve this we simply need to override the ‘to_param’ method in the song model. I imagine that would look something like this:</p>
<pre class="brush: ruby;">
def to_param
number # number is the track number of this song on the album
end</pre>
<p>After this change we would need to modify the controller as params[:id] would return the song number and not the song id. The controllers would need to use</p>
<p>@song = Song.find_by_number(params[:id])<br />
and not<br />
@song = Song.find(params[:id])</p>
<p>There will be more on this in the follow up text editor post.</p>
<h3>Deep Nesting</h3>
<p>Jamis Buck recommends that resources should never be nested more than one level deep. You can find his original post about that <a href="http://weblog.jamisbuck.org/2007/2/5/nesting-resources" target="_blank">here</a>. The Rails community seems to be divided about this ‘rule of thumb’. I recommend that you follow this guideline – although remember it is just a guideline, you can use deeper nesting if the need arises.</p>
<h2>End of Part 6</h2>
<p>This was a quick and short introduction to nested resources. There is a bit more to them, but this enough to start writting Rails applications.</p>
<p>In the follow up, &#8216;plain text editor&#8217;, post we will see a nested route being used a slightly larger application. In that post we will look far more than just routing, that is why I took it out of this part. I will finish that up ASAP.  I hope you have enjoyed this post&#8230;</p>
<p>- Thank you, Daryn</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/73/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/73/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=73&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/07/06/beginners-tutorial-routing-in-rails-20-with-rest-part-6-of-n/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Programming While Stupid</title>
		<link>http://darynholmes.wordpress.com/2008/06/21/programming-while-stupid/</link>
		<comments>http://darynholmes.wordpress.com/2008/06/21/programming-while-stupid/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 14:37:23 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[lean software development]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=69</guid>
		<description><![CDATA[Over engineering is a major problem within the software industry. This problem has led to the adoption of ‘lean software development’ &#8211; at least amongst the agile folk. Lean software development is writing code to support the current set of requirements and nothing more. This is not as easy to do as one might think.
As [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=69&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Over engineering is a major problem within the software industry. This problem has led to the adoption of ‘lean software development’ &#8211; <em>at least amongst the agile folk</em>. Lean software development is writing code to support the current set of requirements and nothing more. This is not as easy to do as one might think.</p>
<p>As developers we naturally tend to make assumptions as to what the user, or system, will need. In truth, it is very difficult to accurately predict the future requirements of a system. Coding to meet our assumptions will inevitably lead to over engineering.</p>
<p>We should not let our intuition guide us into false requirements. As strange as it may sound, it takes a concious effort to stop ourselves from doing extra work. We need to adopt a &#8216;lean coding culture&#8217;. We need to constantly remind our selves to stick to lean software development. In agile teams it is common to hear developers reminding each other with certain acronyms and expressions e.g. &#8216;do the simplest thing that works&#8217;.</p>
<p>‘Do the simplest thing that works’ is in-line with lean software development, although it can be misleading.  Some people interpret this as &#8216;do the first thing that comes to mind&#8217; e.g. slap on another if statement &#8211; that is a simplistic solution and not a simple solution. If you take a quick and dirty simplistic approach you will end up with a <a href="http://www.laputan.org/mud/mud.html#BigBallOfMud" target="_blank">big ball of mud</a>. You need to do the simplest thing that <em>works</em>. The thing that <em>works</em> is something that can be tested, it is something that does not add unnecessary complexity. Therefore the simplest thing that works is not necessarily the quickest and easiest thing to do.</p>
<p><span id="more-69"></span>When talking about lean software development we often refer to KISS (Keep It Simple Stupid). I agree with keeping things simple but I don’t like to be called stupid, <em>the truth hurts</em>. I prefer to use: Keep It Simple and Sensible. This is more positive and the sensible part indicates that we should give some thought to our code. For example, instead of littering your code with conditional statements you could refactor the code to use an established design pattern. Having said that, design patterns are not always a good idea.</p>
<p>You should not implement a design pattern unless there are real signs indicating that you need a smarter solution. It can be detrimental to implement a design pattern for the sake of having one. You are likely to implement the wrong pattern and that code will be a hindrance. Only do what you really <em>need</em> to do. This is also referred to as YAGNI.</p>
<p>YAGNI (You Ain’t Gonna Need It) – This is a term used by Russ Olsen in <a href="http://www.rubyinside.com/design-patterns-in-ruby-by-russ-olsen-695.html" target="_blank">Design Patterns in Ruby</a>. In this book, Russ Olsen does a fantastic job of explaining design patterns. He also explains when not to use certain patterns and the problems that come with using each pattern &#8211; <em>After all, software is about trade off&#8217;s.</em></p>
<p>Russ Olsen explains that we should not write code or implement patterns in anticipation of  a requirement that might emerge. Firstly that requirement may never surface, and if it does it may have a stipulation which makes the pre-emptive solution void. It is safer to code to meet the current and real requirements of the system. To drive this point home, here is a <em>delightful </em>paragraph from Russ Olsens’ Design Patterns in Ruby:</p>
<p>“Look at it this way: Barring a sharp blow to the head, as you stand here today you are as dumb as you ever will be. We are all learning, getting smarter every day. This is especially true in software projects: You can be sure that you will have a better grasp of the requirements, technology, and design of any software that you work on at the end of the project then at the beginning. Whenever you put in a feature before you really need it, you are guilty of programming while stupid; if you wait until you really do need the thing, you are likely to have a better understanding of what you need to do and how you should go about doing it.”</p>
<p>The moral is: Don&#8217;t be guilty of programming while stupid</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/69/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/69/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/69/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=69&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/06/21/programming-while-stupid/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
		<item>
		<title>Beginners Tutorial: Routing in Rails 2.0 (with REST) &#8211; Part 5 of n</title>
		<link>http://darynholmes.wordpress.com/2008/05/26/beginners-tutorial-routing-in-rails-20-with-rest-part-5-of-n/</link>
		<comments>http://darynholmes.wordpress.com/2008/05/26/beginners-tutorial-routing-in-rails-20-with-rest-part-5-of-n/#comments</comments>
		<pubDate>Mon, 26 May 2008 14:32:32 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Routing]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=65</guid>
		<description><![CDATA[Part 6
In part 4 we explored named routes. In this session we move onto Rails&#8217; REST.
Part 5
The Critics
Before we begin you should know that there are many critics of the Rails implementation of REST. There are many reasons for arguments against Rails&#8217; REST e.g. Rails uses server side session state and client side cookies. Some [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=65&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:right;"><strong><a href="http://darynholmes.wordpress.com/2008/07/06/beginners-tutorial-routing-in-rails-20-with-rest-part-6-of-n/" target="_self"><strong>Part 6</strong></a></strong></p>
<p>In <a href="http://darynholmes.wordpress.com/2008/05/11/beginners-tutorial-routing-in-rails-20-with-rest-part-4-of-n/" target="_self">part 4</a> we explored named routes. In this session we move onto Rails&#8217; REST.</p>
<h2>Part 5</h2>
<h3>The Critics</h3>
<p>Before we begin you should know that there are many critics of the Rails implementation of REST. There are many reasons for arguments against Rails&#8217; REST e.g. Rails uses server side session state and client side cookies. Some people say that this is not REST compliant. Rails&#8217; REST might not be 100% REST compliant, but you can still benefit from using REST in your Rails applications. In <a href="http://www.samedaybooks.co.uk/details.php?isbn=9780321445612&amp;s=gb" target="_blank">The Rails Way</a>, <a href="http://blog.obiefernandez.com/" target="_blank">Obie Fernandez</a> explains that the benefits from using Rails&#8217; REST fall into two categories:</p>
<ul>
<li>Convenience and automatic best practices for you</li>
<li>A REST interface to your application for the rest of the world</li>
</ul>
<p>Therefore it is worth learning and using Rails&#8217; REST.</p>
<h3>The Standard Introduction</h3>
<p><strong>Re</strong>presentational <strong>S</strong>tate <strong>T</strong>ransfer (REST) is an architectural style. It was first introduced by <a href="http://en.wikipedia.org/wiki/Roy_Fielding" target="_blank">Roy Fielding</a> in his <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm" target="_blank">PhD thesis</a>. Roy Fielding is one of the principal authors of HTTP.</p>
<h3>The Mindset</h3>
<p>When developing a Rails application in the RESTful way it helps to change your mindset. You should not think that you are developing a web site for users accessing the site via a browser. It is better to think of the application as being a service. The service performs actions for clients. These clients may be humans or other machines on the network.</p>
<p>This service will typically be placed on the internet. Therefore we could call it a web service. When I hear the term <em>web service</em> I immediately start thinking about SOAP and all the WS-* specifications. Let&#8217;s be clear, we are not talking about ‘those&#8217; web services. We are talking about RESTful web services. These two technologies provide similar functionality, but RESTful web services are simple and sensible.</p>
<h3>The Terminology</h3>
<p>As previously stated, programming in REST requires a change in the way we think about the system. This naturally leads to a change in the way we talk about the system. The following provides a brief description of some of the key terms used in discussions about REST and HTTP.</p>
<p>A <strong>resource</strong> is one of the key concepts in REST.  Many discussions on REST claim that a resource is anything and everything. This is neither true nor helpful. Let&#8217;s examine this concept with the aid of an example.</p>
<p>Let&#8217;s assume that the music store has started selling albums. The database may have the following schema:</p>
<p><a href="http://darynholmes.files.wordpress.com/2008/05/orders-erd.png"><img class="alignnone size-full wp-image-66" src="http://darynholmes.files.wordpress.com/2008/05/orders-erd.png?w=450&#038;h=132" alt="orders erd" width="450" height="132" /></a></p>
<p>The data in the database is the raw data. There is data which, given in isolation, is of no real value to a client. For instance it is unlikely that a client will want only one row from the LineItems table. This means that a LineItem (on its own) is not a resource within the context of the music store service.</p>
<p>A client would want all the information pertaining to an order. This would include data from one or more tables. Some data would not be included e.g. database keys. Some information may be added e.g. the total cost of the order might be calculated and included in the ‘order information&#8217;. This ‘order information&#8217; is an example of a resource. <em>Order resource is the type, there will be one order resource instance for each order made</em>.</p>
<p>Each resource must be given a globally unique identifier. This is done using a URI. This could look like this:</p>
<p>http://www.example.com/orders/65</p>
<p>A client, in an admin role, may want a list of all the orders. This collection of orders would be another resource. Following the REST architecture, the orders resource would be assigned the following URL:</p>
<p>http://www.example.com/orders</p>
<p>It is important to note that these resources are not HTML documents. Roy Fielding describes a resource as a conceptual mapping. As a resource is a conceptual entity it can not be used by a client. The service provides the client with a <strong>representation</strong> of the resource.</p>
<p>When the client is a browser, the service typically provides an HTML representation of the resource. If the client is another machine then the service may provide an XML representation of the resource. Other representations could include a PDF file, an image, csv etc. A representation is only supported by the service if it is applicable and required.</p>
<p>Resources are often referred to as <strong>nouns</strong>. This is often done when talking about HTTP to assist learning. The term ‘noun&#8217; is more abstract. For our purposes, resources and ‘nouns&#8217; are synonymous.</p>
<p>HTTP also has the notion of <strong>verbs</strong>. These are the HTTP operations.  We are all familiar with the POST and GET operations. In addition to these two operations, HTTP also supports: DELETE and PUT.</p>
<p>There are a few more terms to cover, but we can do that later. The core terms have been explained.</p>
<p><span id="more-65"></span></p>
<h3>Joining The Dots&#8230;</h3>
<p>REST is an architecture style which makes full use of HTTP. Some say that it makes proper use of HTTP.</p>
<p>As previously explained, HTTP supports GET, POST, DELETE and PUT. One of the main ideas behind REST is to use these HTTP operations to determine the correct action to perform. Let&#8217;s clarify this with an example.</p>
<p>If the RESTful music store server receives a URL of: /albums/4 sent with a GET, then the server will invoke the show action of the albums controller. The response may be an HTML page showing details of the 4th album.</p>
<p>If the server receives a URL of: /albums/4 sent with a DELETE, then the server will invoke the destroy action of the albums controller. This will result in the 4th album being deleted.</p>
<p>Note that the URL did not contain explicit ‘show&#8217; or ‘delete&#8217; information. The server was able to infer the action by examining the HTTP operation. Therefore show and delete were implicitly called.</p>
<p>The form of that URL is REST compliant. If the music store had to include Artists and Songs, we could expect to see URLs like this:<br />
/artists/2<br />
/songs/8</p>
<p>As you can see a consistent API is forming, this is the REST API. It becomes intuitive once you start getting familiar with it. For instance I am sure you can tell what would happen if we did a DELETE on this URL:<br />
/songs/154</p>
<p>An application typically performs the full set of CRUD operations &#8211; Create Read Update and Delete. The following table shows the mapping between database CRUD operations, the HTTP verbs, and REST compliant URLs.</p>
<table border="1" cellpadding="5">
<tbody>
<tr>
<th>Database</th>
<th>HTTP Operation</th>
<th>URL Path</th>
</tr>
<tr>
<td>Create</td>
<td>POST</td>
<td>/albums</td>
</tr>
<tr>
<td>Read</td>
<td>GET</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Update</td>
<td>PUT</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Delete</td>
<td>DELETE</td>
<td>/albums/1</td>
</tr>
</tbody>
</table>
<p>When creating a new album, the plural /albums is used. This is because we are adding a one new album to the collection of albums.</p>
<p>In previous posts in this series, creating and editing an album has always involved two controller actions being invoked. When we create an album we:</p>
<ol>
<li>Call the new action to retrieve a form with empty fields</li>
<li>Call the create action which creates a new album extracting the information from that form</li>
</ol>
<p>When doing an update we:</p>
<ol>
<li>Call the edit action to get a form with fields filled in with data from the relevant album</li>
<li>Call the update action which then performs the actual database update</li>
</ol>
<p>This is the typical behaviour of a website. We need to fit this behaviour in with REST. When doing an edit we can&#8217;t obtain the albums details by doing a GET on /album/1 &#8211; that is already used for showing an album.</p>
<p>This functionality is achieved with <strong>modifiers</strong> (also called <strong>adjectives</strong>). The modifiers we need are ‘new&#8217; and ‘edit&#8217;. This results in the following mapping:</p>
<table border="1" cellpadding="5">
<tbody>
<tr>
<th>Database</th>
<th>Controller Action</th>
<th>HTTP Operation</th>
<th>URL path</th>
</tr>
<tr>
<td>Create</td>
<td>create</td>
<td>POST</td>
<td>/albums</td>
</tr>
<tr>
<td>Read</td>
<td>show</td>
<td>GET</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Update</td>
<td>update</td>
<td>PUT</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Delete</td>
<td>destroy</td>
<td>DELETE</td>
<td>/albums/1</td>
</tr>
<tr>
<td>-</td>
<td>new</td>
<td>GET</td>
<td>/albums/new</td>
</tr>
<tr>
<td>Read</td>
<td>edit</td>
<td>GET</td>
<td>/albums/1/edit</td>
</tr>
<tr>
<td>Read</td>
<td>index</td>
<td>GET</td>
<td>/albums</td>
</tr>
</tbody>
</table>
<p>Note the last line which calls the index action.</p>
<p>As you can tell, we are moving towards Rails specific terminology. I guess this means it is time to step into the code&#8230;</p>
<h3>Experiment 5.0 Preparation</h3>
<p>In <a href="http://darynholmes.wordpress.com/2008/05/11/beginners-tutorial-routing-in-rails-20-with-rest-part-4-of-n/" target="_self">part 4</a> we created named routes. The routes.rb file looked like this:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

 map.albums 'albums',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;index&quot;

 map.album 'album/:id',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;show&quot;

 map.edit_album 'albums/:id/edit',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;edit&quot;

 map.update_album 'albums/:id/update',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;update&quot;  

 map.destroy_album 'albums/:id/destroy',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;destroy&quot;     

 map.new_album 'albums/new',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;new&quot;  

 map.create_album 'albums/create',
 :controller =&gt; &quot;albums&quot;,
 :action =&gt; &quot;create&quot;  

 #map.connect ':controller/:action/:id'
 #map.connect ':controller/:action/:id.:format'

end
</pre>
<p>In this session we move from named routes to RESTful routing. Therefore we can delete these named routes. Empty the routes.rb file:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

 #map.connect ':controller/:action/:id'
 #map.connect ':controller/:action/:id.:format'

end
</pre>
<p>Once again we have a broken music store. Let&#8217;s fix it and make it REST compliant.</p>
<h3>Experiment 5.1 Including REST Routes</h3>
<p>We want the music store application to be REST compliant. At the moment we don&#8217;t make use of the HTTP operations, instead we explicitly state the intentions within the URL. At the end of part 4 the site worked like this:</p>
<table border="1" cellpadding="2">
<tbody>
<tr>
<th>Database</th>
<th>Controller Action</th>
<th>HTTP Operation</th>
<th>URL path</th>
</tr>
<tr>
<td>Create</td>
<td>create</td>
<td>POST</td>
<td bgcolor="#cc0000">/albums/create</td>
</tr>
<tr>
<td>Read</td>
<td>show</td>
<td>GET</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Update</td>
<td>Update</td>
<td bgcolor="#cc0000">POST</td>
<td bgcolor="#cc0000">/albums/1/update</td>
</tr>
<tr>
<td>Delete</td>
<td>destroy</td>
<td bgcolor="#cc0000">GET</td>
<td bgcolor="#cc0000">/albums/1/destroy</td>
</tr>
<tr>
<td>-</td>
<td>new</td>
<td>GET</td>
<td>/albums/new</td>
</tr>
<tr>
<td>Read</td>
<td>edit</td>
<td>GET</td>
<td>/albums/1/edit</td>
</tr>
<tr>
<td>Read</td>
<td>index</td>
<td>GET</td>
<td>/albums</td>
</tr>
</tbody>
</table>
<p>The application was fairly similar to REST. This is because the named routes created in part 4 were based on the REST style. To make the application more RESTful we need to make use of the HTTP verbs. We could update each of our named routes to explicitly state the HTTP operation e.g.</p>
<pre class="brush: ruby;">
  map.albums 'albums',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;index&quot;,
    :method =&gt; &quot;get&quot;
 </pre>
<p>Rails has made this easier for us. Update the routes.rb file to:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  map.resources :albums

  #map.connect ':controller/:action/:id'
  #map.connect ':controller/:action/:id.:format'

end
</pre>
<p>Thanks to this one line, Rails will create a set of named routes &#8211; intelligent named routes. They are intelligent because they examine the request URL as well as the specified HTTP operation. Therefore the same URL can be routed to deferent controller actions.</p>
<p>As you may recall from part 4, when you use named routes Rails dynamically generates routing helper methods. These helper methods are also available on these new &#8216;intelligent&#8217; named routes.</p>
<h3>Experiment 5.2 Showing the Index Page</h3>
<p>Let&#8217;s have a look at the table:</p>
<table border="1" cellpadding="5">
<tbody>
<tr>
<th>Database</th>
<th>Controller Action</th>
<th>HTTP Operation</th>
<th>URL path</th>
</tr>
<tr>
<td>Create</td>
<td>create</td>
<td>POST</td>
<td>/albums</td>
</tr>
<tr>
<td>Read</td>
<td>show</td>
<td>GET</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Update</td>
<td>update</td>
<td>put</td>
<td>/albums/1</td>
</tr>
<tr>
<td>Delete</td>
<td>destroy</td>
<td>DELETE</td>
<td>/albums/1</td>
</tr>
<tr>
<td>-</td>
<td>new</td>
<td>GET</td>
<td>/albums/new</td>
</tr>
<tr>
<td>Read</td>
<td>edit</td>
<td>GET</td>
<td>/albums/1/edit</td>
</tr>
<tr>
<td>Read</td>
<td>index</td>
<td>GET</td>
<td>/albums</td>
</tr>
</tbody>
</table>
<p>To show a list of albums we need to perform a GET with a URL of /albums. We can perform a get by simply typing the URL into the browser and pressing enter. If you try that you should end up with an error.</p>
<p>undefined method `destroy_album_path&#8217; for #</p>
<p>This is good news as we did not get a route not found error. To get the index page up and running we need to replace the named route helper methods we introduced in part 4 with the helper methods created by &#8216;map.resources :albums&#8217;. The following table shows these ‘new&#8217; helper methods.</p>
<table border="1" cellpadding="5">
<tbody>
<tr>
<th>Helper Method</th>
<th>Controller Action</th>
<th>HTTP Operation</th>
<th>URL Path</th>
</tr>
<tr>
<td>albums_url</td>
<td>create</td>
<td>POST</td>
<td>/albums</td>
</tr>
<tr>
<td>album_url(@album)</td>
<td>show</td>
<td>GET</td>
<td>/albums/1</td>
</tr>
<tr>
<td>album_url(@album)</td>
<td>update</td>
<td>put</td>
<td>/albums/1</td>
</tr>
<tr>
<td>album_url(@album)</td>
<td>destroy</td>
<td>DELETE</td>
<td>/albums/1</td>
</tr>
<tr>
<td>new_album_url</td>
<td>new</td>
<td>GET</td>
<td>/albums/new</td>
</tr>
<tr>
<td>edit_album_url</td>
<td>edit</td>
<td>GET</td>
<td>/albums/1/edit</td>
</tr>
<tr>
<td>albums_url</td>
<td>index</td>
<td>GET</td>
<td>/albums</td>
</tr>
</tbody>
</table>
<p>This table shows methods ending with _url, the _path versions also exist. This was explained in part 4. By making use of these helper methods we can update the index.html.erb.</p>
<p>Thanks to our foresight in part 4, we only need to change the call to delete, from:</p>
<p>link_to &#8216;Destroy&#8217;, destroy_album_path(album.id), :confirm =&gt; &#8216;Are you sure?</p>
<p>To</p>
<p>link_to &#8216;Destroy&#8217;, album_path(album), :confirm =&gt; &#8216;Are you sure?&#8217;, :method =&gt; :delete</p>
<p>Just to be clear, the index.html.erb should look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Listing albums&lt;/h1&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Review&lt;/th&gt;
&lt;/tr&gt;
&lt;% for album in @albums %&gt;
&lt;tr&gt;
&lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to 'Show', album_path(album)  %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to 'Edit', edit_album_path(album) %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to 'Destroy', album_path(album), :confirm =&gt; 'Are you sure?', :method =&gt; :delete %&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;% end %&gt;&lt;/table&gt;
&lt;%= link_to 'New album', new_album_path %&gt;
</pre>
<p>A URL of /albums should show the index page &#8211; test it if you like.</p>
<p><em><span style="color:#ff0000;">Alert!</span></em><br />
Link_to obtains the URL by making use of another Rails method called ‘url_for&#8217;. The following quote is from the Rails documentation and it refers to the parameters being passed into url_for.</p>
<p>&#8220;If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter, you‘ll trigger the named route for that record. The lookup will happen on the name of the class. So passing a Workshop object will attempt to use the workshop_path route&#8221;</p>
<p>This means that we can replace<br />
link_to &#8216;Show&#8217;, album_path(album)<br />
with<br />
link_to &#8216;Show&#8217;, album</p>
<p>And<br />
link_to &#8216;Destroy&#8217;, album_path(album), :confirm =&gt; &#8216;Are you sure?&#8217;, :method =&gt; :delete<br />
with<br />
link_to &#8216;Destroy&#8217;, album, :confirm =&gt; &#8216;Are you sure?&#8217;, :method =&gt; :delete</p>
<p>I am sure this bit of Rails magic has been the cause of much confusion.<br />
This magic is also used in other methods e.g. redirect_to, form_for etc.</p>
<p>The index.html.erb can now look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Listing albums&lt;/h1&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Review&lt;/th&gt;
&lt;/tr&gt;
&lt;% for album in @albums %&gt;
&lt;tr&gt;
&lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to 'Show', album  %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to 'Edit', edit_album_path(album) %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to 'Destroy', album, :confirm =&gt; 'Are you sure?', :method =&gt; :delete %&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;% end %&gt;&lt;/table&gt;
&lt;%= link_to 'New album', new_album_path %&gt;
 </pre>
<p>A URL of /albums should now render the index page.</p>
<h3>Experiment 5.3 The RESTful Show</h3>
<p>Thanks to the naming convention we used in part 4, we do not need to do anything to make show work. Show.html.erb remains like this:</p>
<pre class="brush: ruby;">

  &lt;b&gt;Title:&lt;/b&gt;
  &lt;%=h @album.title %&gt;

  &lt;b&gt;Review:&lt;/b&gt;
  &lt;%=h @album.review %&gt;

&lt;%= link_to 'Edit', edit_album_path(@album) %&gt; |
&lt;%= link_to 'Back', albums_path %&gt;
 </pre>
<h3>Experiment 5.4 Edit RESTfully</h3>
<p>To fix update we need to make use of the following methods in the edit view.</p>
<table border="1" cellpadding="5">
<tbody>
<tr>
<th>Helper Method</th>
<th>Controller Action</th>
<th>HTTP Operation</th>
<th>URL Path</th>
</tr>
<tr>
<td>album_url(@album)</td>
<td>update</td>
<td>put</td>
<td>/albums/1</td>
</tr>
<tr>
<td>edit_album_url</td>
<td>edit</td>
<td>GET</td>
<td>/albums/1/edit</td>
</tr>
</tbody>
</table>
<p>The form_for allows us to use more syntactic sugar.</p>
<p>We could use:<br />
form_for (@album), :url =&gt; album_path(@album)</p>
<p>Or we could use:<br />
form_for (@album)</p>
<p>This means the edit.html.erb should look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Editing album&lt;/h1&gt;
&lt;%= error_messages_for :album %&gt;

&lt;% form_for (@album) do |f| %&gt;

    &lt;b&gt;Title&lt;/b&gt;
    &lt;%= f.text_field :title %&gt;

    &lt;b&gt;Review&lt;/b&gt;
    &lt;%= f.text_area :review %&gt;

    &lt;%= f.submit &quot;Update&quot; %&gt;

&lt;% end %&gt;

&lt;%= link_to 'Show', @album %&gt; |
&lt;%= link_to 'Back', albums_path %&gt;
</pre>
<h3>Experiment 5.5 Putting Delete to REST</h3>
<p>This was fixed when we modified the index.html.erb.</p>
<p>The line was:</p>
<p>link_to &#8216;Destroy&#8217;, album, :confirm =&gt; &#8216;Are you sure?&#8217;, :method =&gt; :delete</p>
<h3>Experiment 5.6 A RESTful Addition</h3>
<p>In order to restore the ‘new’ functionality, make new.html.erb look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;New album&lt;/h1&gt;
&lt;%= error_messages_for :album %&gt;

&lt;% form_for (@album) do |f| %&gt;

    &lt;b&gt;Title&lt;/b&gt;
    &lt;%= f.text_field :title %&gt;

    &lt;b&gt;Review&lt;/b&gt;
    &lt;%= f.text_area :review %&gt;

    &lt;%= f.submit &quot;Create&quot; %&gt;

&lt;% end %&gt;

&lt;%= link_to 'Back', albums_path %&gt;
</pre>
<h3>Experiment 5.7 Updating the Controller to use the Syntactic Sugar</h3>
<p>When using a resource the controller must implement these specific methods:<br />
index, show, new, edit, create, update, destroy.<br />
Our controller already meets this condition.</p>
<p>Although the music store is fully operational, we can make some minor modifications in the controller. This is just to leave the controller in the way Rails generated it in part 1. These changes are in the create and update actions e.g. redirect_to(@album)</p>
<p>The controller should look as follows:</p>
<pre class="brush: ruby;">

class AlbumsController &lt; ApplicationController
  # GET /albums
  # GET /albums.xml
  def index
    @albums = Album.find(:all)
    @cont = &quot;The controller is:&quot; + params[:controller]
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @albums }
    end
  end

  # GET /albums/1
  # GET /albums/1.xml
  def show
    @album = Album.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album }
    end
  end

  # GET /albums/new
  # GET /albums/new.xml
  def new
    @album = Album.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album }
    end
  end

  # GET /albums/1/edit
  def edit
    @album = Album.find(params[:id])
  end

  # POST /albums
  # POST /albums.xml
  def create
     @album = Album.new(params[:album])  

     respond_to do |format|
       if @album.save
         flash[:notice] = 'Album was successfully created.'
         format.html { redirect_to(@album) }
         format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album, :status =&gt; :created, :location =&gt; @album }
       else
         format.html { render :action =&gt; &quot;new&quot; }
         format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album.errors, :status =&gt; :unprocessable_entity }
       end
     end
  end  

  # PUT /albums/1
  # PUT /albums/1.xml
  def update
     @album = Album.find(params[:id])  

     respond_to do |format|
       if @album.update_attributes(params[:album])
         flash[:notice] = 'Album was successfully updated.'
         format.html { redirect_to(@album) }
         format.xml  { head <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> k }
       else
         format.html { render :action =&gt; &quot;edit&quot; }
         format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album.errors, :status =&gt; :unprocessable_entity }
       end
     end
   end  

  # DELETE /albums/1
  # DELETE /albums/1.xml
  def destroy
    @album = Album.find(params[:id])
    @album.destroy

    respond_to do |format|
      format.html { redirect_to(albums_url) }
      format.xml  { head <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> k }
    end
  end
end
</pre>
<p>And that is that – our music store is exactly how it was when we generated it in part 1.</p>
<h3>End of Part 5</h3>
<p>To keep things ‘simple’ I have been skipping over certain aspects of routing. I will draft one more post in this series where I will mention some of these topics. Some of the readers have asked questions, I will still answer those questions but they won’t form part of this tutorial.</p>
<p>That concludes part 5. Hopefully you have a better understanding of what is going on under the hood.</p>
<p>Thank you, Daryn</p>
<p style="text-align:right;"><strong><strong><a href="http://darynholmes.wordpress.com/2008/07/06/beginners-tutorial-routing-in-rails-20-with-rest-part-6-of-n/" target="_self"><strong>Part 6</strong></a></strong></strong></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/65/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/65/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/65/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=65&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/05/26/beginners-tutorial-routing-in-rails-20-with-rest-part-5-of-n/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>

		<media:content url="http://darynholmes.files.wordpress.com/2008/05/orders-erd.png" medium="image">
			<media:title type="html">orders erd</media:title>
		</media:content>
	</item>
		<item>
		<title>Beginners Tutorial: Routing in Rails 2.0 (with REST) &#8211; Part 4 of n</title>
		<link>http://darynholmes.wordpress.com/2008/05/11/beginners-tutorial-routing-in-rails-20-with-rest-part-4-of-n/</link>
		<comments>http://darynholmes.wordpress.com/2008/05/11/beginners-tutorial-routing-in-rails-20-with-rest-part-4-of-n/#comments</comments>
		<pubDate>Sun, 11 May 2008 21:26:03 +0000</pubDate>
		<dc:creator>darynholmes</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Beginner]]></category>
		<category><![CDATA[IRB]]></category>
		<category><![CDATA[Routing]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://darynholmes.wordpress.com/?p=64</guid>
		<description><![CDATA[Part 5
The routes we have discussed so far are known as simple routes. I have been referring to them as custom routes, but ‘simple routes’ is the correct term. The default route we discussed in part 3 is also a simple route. The aim is to move onto RESTful routes, sometimes called resource routes. RESTful [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=64&subd=darynholmes&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:right;"><a href="http://darynholmes.wordpress.com/2008/05/26/beginners-tutorial-routing-in-rails-20-with-rest-part-5-of-n/" target="_self"><strong>Part 5</strong></a></p>
<p>The routes we have discussed so far are known as <strong>simple routes</strong>. I have been referring to them as custom routes, but ‘simple routes’ is the correct term. The <strong>default route</strong> we discussed in <a href="http://darynholmes.wordpress.com/2008/04/27/beginners-tutorial-routing-in-rails-20-with-rest-part-3-of-n/">part 3</a> is also a simple route. The aim is to move onto <strong>RESTful routes</strong>, sometimes called resource routes. RESTful routes are built on top of <strong>named routes</strong>. Therefore we must first cover named routes, and that is what part 4 is all about.</p>
<h2>Part 4</h2>
<h3>Introduction</h3>
<p>Referring back to part 1, the routing system has two main functions:<br />
Interpreting a request URL<br />
Generating a request URL</p>
<p>We had a detailed look at route generation and interpretation in part 2, but let’s have another quick look at it. Let’s assume, for some insane reason, that we defined the following route in the music_store routes.rb file:</p>
<p>map.connect &#8216;apples/bananas/:id&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;show&#8221;</p>
<p>link_to would use this rule to generate a URL, this can be seen in the following line extracted from index.html.erb:</p>
<p>link_to &#8216;Show&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;show&#8221;, :id =&gt; album.id</p>
<p>This could generate a URL of: http://localhost:3000/apples/bananas/7<br />
And when given this request, Rails would handle it correctly e.g. the show action will be called on the albums controller and the show view will be sent as the response to the browser.</p>
<p>Coming back to the real world, we are more likely to define the routing rule like this:<br />
map.connect &#8216;albums/show/:id&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;show&#8221;</p>
<p>link_to (and friends) would then generate a URL like this:<br />
http://localhost:3000/albums/show/7.</p>
<p>To show the index (the listing of the albums) we could define a rule like this:<br />
map.connect &#8216;albums/index&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;</p>
<p>The matching link_to in edit.html.erb is:<br />
link_to &#8216;Back&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;</p>
<p>Looking at the last example, there is some repetition. Both lines contain:<br />
:controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;</p>
<p>The link_to method needs this (controller, action) information to obtain the URL. If we had the URL stored as some global variable, or method, then we could simply pass that into link_to. link_to could use this ‘literal’ URL without needing to generate one.<br />
This could look something like: link_to &#8216;Back&#8217;, albums_index_url<br />
This is one of the main ideas behind named routes.</p>
<p><span id="more-64"></span></p>
<h3>Named Routes</h3>
<p>Named routes provide a way to ‘clean up’ code, specifically the code within link_to and other similar functions. When a named route is defined, new helper methods are dynamically generated. These helper methods provide a simplified way of obtaining the required request URL. The names of these helper methods are based on the name of the route. Let’s clarify this by coding.</p>
<h3>Experiment 4.0 Preparation</h3>
<p>At the end of part 3 the routes.rb had the default route in it:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  map.connect ':controller/:action/:id'

end
</pre>
<p>It is common to accompany the default route with this:<br />
map.connect &#8216;:controller/:action/:id.:format&#8217;<br />
We can think of this as a default route which allows clients to request a different format for the response. :format was discussed in part 1, under the title of Experimenting 1 &#8211; View the generated routes.</p>
<p>To prepare for this session, we want to remove all the routes and completely break the site. Therefore you should make your routes.rb look like this:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  # map.connect ':controller/:action/:id'
  # map.connect ':controller/:action/:id.:format'

end
</pre>
<p>Now the site is good for two things, serving up routing errors and learning about named routes…</p>
<h3>Experiment 4.1 Adding a Named Route for the Albums Index</h3>
<p>In part 2 we defined a route which invoked the index action on the albums controller. That route looked like this: map.connect &#8216;music&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;</p>
<p>To follow Rails convention, we should write it like this:<br />
map.connect &#8216;albums&#8217;, :controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;</p>
<p>Making it more readable we could write it like this:<br />
map.connect &#8216;albums&#8217;,<br />
:controller =&gt; &#8220;albums&#8221;,<br />
:action =&gt; &#8220;index&#8221;</p>
<p>The pattern string is ‘albums’, therefore a URL of /albums would match.</p>
<p>In order to name this route, we need to decide what to name or call it. A top down approach is recommended for this. We want to show a list of albums, so it seems reasonable to call the route ‘<strong>albums</strong>’.</p>
<p>To name the route, we make a small change to our route definition. We change the route definition from:</p>
<p>map.connect &#8216;albums&#8217;,<br />
:controller =&gt; &#8220;albums&#8221;,<br />
:action =&gt; &#8220;index&#8221;</p>
<p>To:</p>
<p>map.albums &#8216;albums&#8217;,<br />
:controller =&gt; &#8220;albums&#8221;,<br />
:action =&gt; &#8220;index&#8221;</p>
<p>All we had to do is change map.<strong>connect</strong> to map.<strong>albums</strong>. Modify your routes.rb file to look like this:</p>
<pre class="brush: ruby;">
  ActionController::Routing::Routes.draw do |map|  

    map.albums 'albums',
        :controller =&gt; &quot;albums&quot;,
        :action =&gt; &quot;index&quot;

    # map.connect ':controller/:action/:id'
    # map.connect ':controller/:action/:id.:format'

  end
</pre>
<p>Once this file is saved, you will have created a named route. We are still missing most of the routes our site requires therefore we can’t run the site just yet. Let’s simplify the index page. Make the index.html.erb look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Listing albums&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Review&lt;/th&gt;
  &lt;/tr&gt;

&lt;% for album in @albums %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;
</pre>
<p>Now you should be able to see the simplified index page. Next we will take a look at the methods that Rails generates when using named routes.</p>
<h3>Experiment 4.2 Exploring the ‘Named Route’ Generated Methods</h3>
<p>When a named route is defined, Rails will dynamically generate two methods, these are:<br />
name_url and name_path (where name is the name of the route). name_url will return the fully qualified URL, name_path returns the relative path – it does not include the protocol and host.</p>
<p>In our case, we have a route named albums. When we run the site, rails will generate albums_url and albums_path. Let’s make the view display these values, change the index.html.erb to this:<br />
<em>I had to use different formatting to stop WordPress from getting up to its shenanigans&#8230; </em></p>
<pre>&lt;h1&gt;Listing albums&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Review&lt;/th&gt;
  &lt;/tr&gt;

&lt;% for album in @albums %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;
albums_url: &lt;%= albums_url %&gt;
&lt;br /&gt;
albums_path: &lt;%= albums_path %&gt;</pre>
<p>Brows to http://localhost:3000/albums and you should see:<br />
albums_url: http://localhost:3000/albums<br />
albums_path: /albums</p>
<p>Now that we have seen the output of these methods, you can now remove those last three lines.</p>
<p>Academically speaking it is probably more correct to use name_url but name_path also works in most cases. The Rails way is to use name_path if you can. These methods are available in the views and controllers.</p>
<h3>Experiment 4.3 Defining a Named Route for Show</h3>
<p>Showing the index is fairly straight forward as it is basically a static URL. Now we look at defining a named route for show. Show needs to pass through the ID of the specific album. When defining a simple route, we could use:</p>
<p>map.connect &#8216;album/:id&#8217;,<br />
:controller =&gt; &#8220;albums&#8221;,<br />
:action =&gt; &#8220;show&#8221;</p>
<p>Once again, we can convert this into a named route by replacing connect with the name of the route. Let’s name the route ‘album’. Update the routes.rb to look as follows:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  map.albums 'albums',
      :controller =&gt; &quot;albums&quot;,
      :action =&gt; &quot;index&quot;

  map.album 'album/:id',
      :controller =&gt; &quot;albums&quot;,
      :action =&gt; &quot;show&quot;

    # map.connect ':controller/:action/:id'
    # map.connect ':controller/:action/:id.:format'

end
</pre>
<p>Rails realises that it needs a value for :id, therefore the helper methods accept a parameter to be assigned to it. Therefore link_to can use album_url(3). This will hard code 3, but it illustrates the point.</p>
<p>In the code we are likely to use:<br />
link_to &#8216;Show&#8217;, album_path(album.id)<br />
Thanks to some syntactic sugar we can also use:<br />
link_to &#8216;Show&#8217;, album_path(album)</p>
<p>Let’s get the ‘show’ functionality working again. Update index.erb.html to look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Listing albums&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Review&lt;/th&gt;
  &lt;/tr&gt;

&lt;% for album in @albums %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Show', album_path(album)  %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;
</pre>
<p>And update show.erb.html to:</p>
<pre class="brush: ruby;">
&lt;p&gt;
  &lt;b&gt;Title:&lt;/b&gt;
  &lt;%=h @album.title %&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;b&gt;Review:&lt;/b&gt;
  &lt;%=h @album.review %&gt;
&lt;/p&gt;

&lt;%= link_to 'Back', albums_path %&gt;
</pre>
<p>We have removed the link to ‘edit’, we will replace it later.</p>
<p>At this stage the site should be able:</p>
<ul>
<li>to show the list of albums in the index page</li>
<li>show a single album</li>
</ul>
<h3>Experiment 4.4 Defining a Named Route for Edit</h3>
<p>Now lets fix the edit functionality. Update routes.rb to look like this:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  map.albums 'albums',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;index&quot;

  map.album 'album/:id',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;show&quot;

  map.edit_album 'albums/:id/edit',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;edit&quot;

  map.update_album 'albums/:id/update',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;update&quot;  

    # map.connect ':controller/:action/:id'
    # map.connect ':controller/:action/:id.:format'

end
 </pre>
<p>You may have noticed that I am using slightly different pattern strings to what we have been using. The pattern strings (and URLs) that I am using now are fairly close to those used in REST. Therefore we are already getting familiar with the RESTful interface.</p>
<p>Update the index.erb.html to:</p>
<pre class="brush: ruby;">

&lt;h1&gt;Listing albums&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Review&lt;/th&gt;
  &lt;/tr&gt;

&lt;% for album in @albums %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Show', album_path(album)  %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Edit', edit_album_path(album) %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;

 </pre>
<p>Edit.erb.html should look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Editing album&lt;/h1&gt;

&lt;%= error_messages_for :album %&gt;

&lt;% form_for (@album), :url =&gt; update_album_path(@album) do |f| %&gt;
  &lt;p&gt;
    &lt;b&gt;Title&lt;/b&gt;&lt;br /&gt;
    &lt;%= f.text_field :title %&gt;
  &lt;/p&gt;

  &lt;p&gt;
    &lt;b&gt;Review&lt;/b&gt;&lt;br /&gt;
    &lt;%= f.text_area :review %&gt;
  &lt;/p&gt;

  &lt;p&gt;
    &lt;%= f.submit &quot;Update&quot; %&gt;
  &lt;/p&gt;
&lt;% end %&gt;

&lt;%= link_to 'Show', album_path(@album) %&gt; |
&lt;%= link_to 'Back', albums_path %&gt;
</pre>
<p>Add the edit link back to show.erb.html</p>
<pre class="brush: ruby;">
  &lt;p&gt;
  &lt;b&gt;Title:&lt;/b&gt;
  &lt;%=h @album.title %&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;b&gt;Review:&lt;/b&gt;
  &lt;%=h @album.review %&gt;
&lt;/p&gt;

&lt;%= link_to 'Edit', edit_album_path(@album) %&gt; |
&lt;%= link_to 'Back', albums_path %&gt;
</pre>
<p>At this stage the site should be able:</p>
<ul>
<li>to show the list of albums in the index page</li>
<li>show a single album</li>
<li>Edit an existing album</li>
</ul>
<h3>Experiment 4.5 Defining a Named Route for Destroy</h3>
<p>Update the routes.rb to this:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  map.albums 'albums',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;index&quot;

  map.album 'album/:id',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;show&quot;

  map.edit_album 'albums/:id/edit',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;edit&quot;

  map.update_album 'albums/:id/update',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;update&quot;  

  map.destroy_album 'albums/:id/destroy',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;destroy&quot;     

    # map.connect ':controller/:action/:id'
    # map.connect ':controller/:action/:id.:format'

end
</pre>
<p>The index.erb.html should look like this:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Listing albums&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Review&lt;/th&gt;
  &lt;/tr&gt;

&lt;% for album in @albums %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Show', album_path(album)  %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Edit', edit_album_path(album) %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Destroy', destroy_album_path(album.id), :confirm =&gt; 'Are you sure?' %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;
</pre>
<p>I am sure that you are getting a feel for named routes now…</p>
<p>At this stage the site should be able:</p>
<ul>
<li>to show the list of albums in the index page</li>
<li>show a single album</li>
<li>Edit an existing album</li>
<li>Delete an album</li>
</ul>
<h3>Experiment 4.6 Defining a Named Route for New</h3>
<p>Change the routes.rb file to this:</p>
<pre class="brush: ruby;">
ActionController::Routing::Routes.draw do |map|  

  map.albums 'albums',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;index&quot;

  map.album 'album/:id',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;show&quot;

  map.edit_album 'albums/:id/edit',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;edit&quot;

  map.update_album 'albums/:id/update',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;update&quot;  

  map.destroy_album 'albums/:id/destroy',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;destroy&quot;     

  map.new_album 'albums/new',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;new&quot;  

  map.create_album 'albums/create',
    :controller =&gt; &quot;albums&quot;,
    :action =&gt; &quot;create&quot;  

    # map.connect ':controller/:action/:id'
    # map.connect ':controller/:action/:id.:format'

end
</pre>
<p>The index.erb.html should now be:</p>
<pre class="brush: ruby;">
&lt;h1&gt;Listing albums&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Review&lt;/th&gt;
  &lt;/tr&gt;

&lt;% for album in @albums %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%=h album.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%=h album.review %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Show', album_path(album)  %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Edit', edit_album_path(album) %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= link_to 'Destroy', destroy_album_path(album.id), :confirm =&gt; 'Are you sure?' %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;&lt;%= link_to 'New album', new_album_path %&gt;
</pre>
<p><em>To stop WordPress from deleting my code, I put link_to &#8216;New album&#8217;  on the same line as the br tag. They are on separate lines in my actual code.</em></p>
<p>With new.erb.html looking like this:</p>
<pre class="brush: ruby;">

&lt;h1&gt;New album&lt;/h1&gt;

&lt;%= error_messages_for :album %&gt;

&lt;% form_for :album, @album, :url =&gt; create_album_path do |f| %&gt;
  &lt;p&gt;
    &lt;b&gt;Title&lt;/b&gt;&lt;br /&gt;
    &lt;%= f.text_field :title %&gt;
  &lt;/p&gt;

  &lt;p&gt;
    &lt;b&gt;Review&lt;/b&gt;&lt;br /&gt;
    &lt;%= f.text_area :review %&gt;
  &lt;/p&gt;

  &lt;p&gt;
    &lt;%= f.submit &quot;Create&quot; %&gt;
  &lt;/p&gt;
&lt;% end %&gt;

&lt;%= link_to 'Back', albums_path %&gt;
</pre>
<p>At this stage the site should be able:</p>
<ul>
<li>to show the list of albums in the index page</li>
<li>show a single album</li>
<li>Edit an existing album</li>
<li>Add a new album</li>
</ul>
<p>Are we done? What about the controller?</p>
<h3>Experiment 4.7 Using Named Route Helper Methods in the Controller</h3>
<p>Open the controller and look at the destroy action, you will notice this line:</p>
<p>format.html { redirect_to(:controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;) }</p>
<p>This shows you that we can still generate routes as if we were using the simple routes. We have defined named routes, we can use the helper methods in the controller, so we might as well.</p>
<p>Make the controller look like this:</p>
<pre class="brush: ruby;">
class AlbumsController &lt; ApplicationController
  # GET /albums
  # GET /albums.xml
  def index
    @albums = Album.find(:all)
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @albums }
    end
  end

  # GET /albums/1
  # GET /albums/1.xml
  def show
    @album = Album.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album }
    end
  end

  # GET /albums/new
  # GET /albums/new.xml
  def new
    @album = Album.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album }
    end
  end

  # GET /albums/1/edit
  def edit
    @album = Album.find(params[:id])
  end

  # POST /albums
  # POST /albums.xml
  def create
     @album = Album.new(params[:album])  

     respond_to do |format|
       if @album.save
         flash[:notice] = 'Album was successfully created.'
         format.html { redirect_to(album_path(@album)) }
         format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album, :status =&gt; :created, :location =&gt; @album }
       else
         format.html { render :action =&gt; &quot;new&quot; }
         format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album.errors, :status =&gt; :unprocessable_entity }
       end
     end
  end  

  # PUT /albums/1
  # PUT /albums/1.xml
  def update
     @album = Album.find(params[:id])  

     respond_to do |format|
       if @album.update_attributes(params[:album])
         flash[:notice] = 'Album was successfully updated.'
         format.html { redirect_to(album_path(@album)) }
         format.xml  { head <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> k }
       else
         format.html { render :action =&gt; &quot;edit&quot; }
         format.xml  { render <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml =&gt; @album.errors, :status =&gt; :unprocessable_entity }
       end
     end
   end  

  # DELETE /albums/1
  # DELETE /albums/1.xml
  def destroy
    @album = Album.find(params[:id])
    @album.destroy

    respond_to do |format|
      format.html { redirect_to(albums_path) }
      format.xml  { head <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> k }
    end
  end
end
</pre>
<p>Sure we have a larger routes.rb file, but I am sure you will agree that  redirect_to(albums_path)</p>
<p>is much better than redirect_to(:controller =&gt; &#8220;albums&#8221;, :action =&gt; &#8220;index&#8221;)</p>
<h2>The End of Part 4</h2>
<p>I hope this has helped you to get familiar with named routes. There is a lot more to them, and there is also a lot more syntactic sugar. Once I have completed the section on RESTful routing, I might do a summary post. This would be a recap and it will show some tips and tricks that I skipped over in these posts. I am skipping certain topics as I would like to get onto RESTful routing as soon as possible.</p>
<p>Speaking of RESTful routing, the way we have named the routes is very close to the RESTful way. You will see this in the next post.</p>
<p>It is very easy to make mistakes when writing a tutorial like this. Especially with the gremlins inside of the WordPress formatting engine. If you are one of the first to complete this session successfully then please inform me. More importantly, if you find a problem please let me know.</p>
<p>Thank you, Daryn</p>
<p style="text-align:right;"><strong><a href="http://darynholmes.wordpress.com/2008/05/26/beginners-tutorial-routing-in-rails-20-with-rest-part-5-of-n/" target="_self"><strong>Part 5</strong></a></strong></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/darynholmes.wordpress.com/64/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/darynholmes.wordpress.com/64/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darynholmes.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darynholmes.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darynholmes.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darynholmes.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darynholmes.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darynholmes.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darynholmes.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darynholmes.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darynholmes.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darynholmes.wordpress.com/64/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=darynholmes.wordpress.com&blog=2505811&post=64&subd=darynholmes&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://darynholmes.wordpress.com/2008/05/11/beginners-tutorial-routing-in-rails-20-with-rest-part-4-of-n/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be1f59e4118912d487c5330586f39b72?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Daryn</media:title>
		</media:content>
	</item>
	</channel>
</rss>