<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>ASCIIcasts - Full Episode Feed</title>
    <description>The latest episodes from ASCIIcasts</description>
    <link>http://asciicasts.com/</link>
    <pubDate>Fri, 05 Mar 2010 22:31:27 +0000</pubDate>
    <ttl>1440</ttl>
    <item>
      <title>Routing in Rails 3</title>
      <description>&lt;p&gt;We&amp;rsquo;ll continue our look into Rails 3&amp;rsquo;s new features in this episode, this time concentrating on routing. Rails 3 has a new API for defining routes and some new features. To show how the new routing works we&amp;rsquo;ll create a new application called detour and create some routes for it.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails detour
&lt;/pre&gt;
&lt;p&gt;Once we&amp;rsquo;ve created the application we can open it up in a text editor to look at the &lt;code&gt;config/routes.rb&lt;/code&gt; file. The default file contains some documentation and examples of the new API and is worth reading through.  We&amp;rsquo;re going to replace the default contents with an example of some old routes and show their Rails 3 equivalents.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/routes.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
Detour::Application.routes.draw do |map|
  map.resources :products, :member =&amp;gt; { :detailed =&amp;gt; :get }
  
  map.resources :forums, :collection =&amp;gt; { :sortable =&amp;gt; :get, :sort =&amp;gt; :put } do |forums|
    forums.resources :topics
  end
  
  map.root :controller =&amp;gt; &amp;quot;home&amp;quot;, :action =&amp;gt; &amp;quot;index&amp;quot;
  
  map.about &amp;quot;/about&amp;quot;, :controller =&amp;gt; &amp;quot;info&amp;quot;, :action =&amp;gt; &amp;quot;about&amp;quot;
end
&lt;/pre&gt;
&lt;p class="title"&gt;The old-style routes that we&amp;rsquo;re going to convert.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll start with the first route in the collection above:&lt;/p&gt;
&lt;pre class="ruby"&gt;
map.resources :products, :member = { :detailed =&amp;gt; :get }
&lt;/pre&gt;
&lt;p&gt;This route has a products resource and a specific additional member action called detailed which is called via a GET request.&lt;/p&gt;

&lt;p&gt;The first change to note in Rails 3&amp;rsquo;s routing is that we no longer deal with the &lt;code&gt;map&lt;/code&gt; object, instead calling &lt;code&gt;resources&lt;/code&gt; directly in the &lt;code&gt;routes.draw&lt;/code&gt; block. &lt;code&gt;:member&lt;/code&gt; and &lt;code&gt;:collection&lt;/code&gt; actions inside resources are defined inside a block. The route can therefore be rewritten like this:&lt;/p&gt;
&lt;pre class="ruby"&gt;
resources :products do
  get :detailed, :on =&amp;gt; :member
end
&lt;/pre&gt;
&lt;p&gt;Next we&amp;rsquo;ll look at a more complex route:&lt;/p&gt;
&lt;pre class="ruby"&gt;
map.resources :forums, :collection =&amp;gt; { :sortable =&amp;gt; :get, :sort =&amp;gt; :put } do |forums|
  forums.resources :topics
end
&lt;/pre&gt;
&lt;p&gt;In this route we have a forum resource with two additional collection items and a nested topics resource. With the new API this route can be written like this:&lt;/p&gt;
&lt;pre class="ruby"&gt;
resources :forums do
  collection do
    get :sortable
    put :sort
  end
  resources :topics
end
&lt;/pre&gt;
&lt;p&gt;Again we use &lt;code&gt;resources&lt;/code&gt; instead of &lt;code&gt;map.resources&lt;/code&gt; and pass in a block. We have two collection actions in the route. While we could define those in the same way we did with the detailed action in the first route making use of the &lt;code&gt;:on&lt;/code&gt; argument instead we&amp;rsquo;ll define a &lt;code&gt;collection&lt;/code&gt; block (members can be treated the same way in a &lt;code&gt;member&lt;/code&gt; block) and any routes defined inside the block will act on the collection of forums. In our block we&amp;rsquo;ve defined two new actions sortable as a GET request and sort as a PUT.&lt;/p&gt;

&lt;p&gt;For the nested topics resource we just call &lt;code&gt;resources&lt;/code&gt; again, nesting the topics resource inside forums.&lt;/p&gt;

&lt;p&gt;The next route we&amp;rsquo;ll look at is the one that defines the controller and action that the root URL point to:&lt;/p&gt;
&lt;pre class="ruby"&gt;
map.root :controller =&amp;gt; &amp;quot;home&amp;quot;, :action =&amp;gt; &amp;quot;index&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Here we can just call &lt;code&gt;root&lt;/code&gt; and use a &lt;code&gt;:to&lt;/code&gt; argument to which we pass a string that contains the name of the controller and action separated by a hash.&lt;/p&gt;
&lt;pre class="ruby"&gt;
root :to =&amp;gt; &amp;quot;home#index&amp;quot;
&lt;/pre&gt;
&lt;p&gt;This ability to specify a controller and action in a single string is a new feature of Rails 3. We can do something similar for a named route:&lt;/p&gt;
&lt;pre class="ruby"&gt;
map.about &amp;quot;/about&amp;quot;, :controller =&amp;gt; &amp;quot;info&amp;quot;, :action =&amp;gt; &amp;quot;about&amp;quot;
&lt;/pre&gt;
&lt;p&gt;With the Rails 3 API this can be rewritten like this:&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/about&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;, :as =&amp;gt; :about
&lt;/pre&gt;
&lt;p&gt;Without the &lt;code&gt;:as&lt;/code&gt; argument the route above would just be a generic route. Adding  &lt;code&gt;:as&lt;/code&gt; makes it a named route so that we can use &lt;code&gt;about_path&lt;/code&gt; or &lt;code&gt;about_url&lt;/code&gt; in our application.&lt;/p&gt;

&lt;h3&gt;New Features&lt;/h3&gt;

&lt;p&gt;As you can see from the examples above it&amp;rsquo;s not difficult to convert routes from the old API to the new one but what really makes the new routing API interesting is the new features it provides and we&amp;rsquo;ll spend the rest of the episode covering some of them.&lt;/p&gt;

&lt;h4&gt;Optional Parameters&lt;/h4&gt;

&lt;p&gt;Optional parameters were supported in previous versions of Rails but the syntax was a little clumsy. Lets see how it&amp;rsquo;s done in Rails 3.&lt;/p&gt; 

&lt;p&gt;It will be easier to demonstrate optional parameters if our application has a controller so we&amp;rsquo;ll create an &lt;code&gt;info&lt;/code&gt; controller with an about action. Note that in Rails 3 we can use &lt;code&gt;rails g&lt;/code&gt; as a shortcut for &lt;code&gt;rails generate&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails g controller info about
&lt;/pre&gt;
&lt;p&gt;We can start up our server with another new shortcut:&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails s
&lt;/pre&gt;
&lt;p&gt;Now, if we visit &lt;a href="http://localhost:3000/about"&gt;http://localhost:3000/about&lt;/a&gt; we&amp;rsquo;ll see the &lt;code&gt;info#about&lt;/code&gt; action as determined by the routes we wrote earlier.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/332/original/E203I01.png" width="797" height="280" alt="The about action."/&gt;
&lt;/div&gt;

&lt;p&gt;With that working we want to provide a PDF version of this action but if we visit &lt;a href="http://localhost:3000/about.pdf"&gt;http://localhost:3000/about.pdf&lt;/a&gt; we&amp;rsquo;ll get a routing error as our application doesn&amp;rsquo;t know how to match the route.&lt;/p&gt;

&lt;p&gt;In the routes file we can change the &lt;code&gt;about&lt;/code&gt; route to accept a format parameter by adding a full stop and &lt;code&gt;:format&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/about.:format&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;, :as =&amp;gt; :about
&lt;/pre&gt;
&lt;p&gt;If we reload PDF view now the route will be matched but we&amp;rsquo;ll see a missing template error as our application doesn&amp;rsquo;t know how to render that action as a PDF.&lt;/p&gt; 

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/333/original/E203I02.png" width="797" height="280" alt="The PDF route is now matched."/&gt;
&lt;/div&gt;

&lt;p&gt;It looks like we&amp;rsquo;ve fixed the problem but the format isn&amp;rsquo;t optional so when we go back to the default view for that page we&amp;rsquo;ll get a routing error. Fortunately it&amp;rsquo;s easy to make part of a route optional: all we need to do is wrap the optional part in parentheses, like this:&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/about(.:format)&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;, :as =&amp;gt; :about
&lt;/pre&gt;
&lt;p&gt;Now we can visit either &lt;a href="http://localhost:3000/about"&gt;http://localhost:3000/about&lt;/a&gt; or &lt;a href="http://localhost:3000/about.pdf"&gt;http://localhost:3000/about.pdf&lt;/a&gt; without seeing a routing error.&lt;/p&gt;

&lt;p&gt;Next we&amp;rsquo;ll show you how to use more complex optional parameters. Let&amp;rsquo;s say that our application has a number of blog articles that we want to filter by specifying a year with an optional month (or month and day) in the URL.&lt;/p&gt;

&lt;p&gt;We can do this by defining a route like this, directing any matching route to our &lt;code&gt;info#about&lt;/code&gt; action. Note that we can nest parentheses when creating optional parameters.&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/:year(/:month(/:day))&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;
&lt;/pre&gt;
&lt;p&gt;In the view code we&amp;rsquo;ll add some debug code so that we can see what parameters are being passed in:&lt;/p&gt;
&lt;p class="codeFilePath"&gt;/app/views/info/about.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;h1&amp;gt;Info#about&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;Find me in app/views/info/about.html.erb&amp;lt;/p&amp;gt;
&amp;lt;%= debug params %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now if we specify a year in the URL it will be passed into the about action and likewise if we specify a year, month and day all three parameters are passed.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/334/original/E203I03.png" width="798" height="280" alt="The date paramters are passed to the route."/&gt;
&lt;/div&gt;

&lt;p&gt;This route is fairly generic though and if we were to visit, say, &lt;a href="http://localhost:3000/foo/bar"&gt;http://localhost:3000/foo/bar&lt;/a&gt; this will also be passed through to the about action when we only want parameters that look like a date to be passed. We can do this with constraints.&lt;/p&gt; 

&lt;h4&gt;Constraints&lt;/h4&gt;

&lt;p&gt;Constraints are available in Rails 2 where they&amp;rsquo;re known as requirements. We can pass a &lt;code&gt;:constraints&lt;/code&gt; option to our route with a hash of the values and the constraints that each one should match. We&amp;rsquo;ll constrain the route so that it will only match if the the year parameter is four digits and the month and day parameters are two digits:&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/:year(/:month(/:day))&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;, :constraints =&amp;gt; { :year =&amp;gt; /\d{4}/, :month =&amp;gt; /\d{2}/, :day =&amp;gt; /\d{2}/ }
&lt;/pre&gt;
&lt;p&gt;With this constraint in place when we visit the &lt;code&gt;/foo/bar&lt;/code&gt; path again we get a routing error as the path doesn&amp;rsquo;t match the date constraints.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/335/original/E203I04.png" width="798" height="280" alt="The route now doesn't match unless the parameters match a date."/&gt;
&lt;/div&gt;

&lt;p&gt;What we&amp;rsquo;ve done with constraints so far was possible with Rails 2&amp;rsquo;s requirements but with constraints in Rails 3 we can do much more. For example we can use a &lt;code&gt;user_agent&lt;/code&gt; parameter to restrict a route to a specific browser, in this case Firefox.&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/secret&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;, :constraints =&amp;gt; { :user_agent =&amp;gt; /Firefox/ }
&lt;/pre&gt;
&lt;p&gt;If we visit &lt;a href="http:/localhost:3000/secret"&gt;http:/localhost:3000/secret&lt;/a&gt; in Safari, Chrome or Opera we&amp;rsquo;ll see a routing error but if we visit in Firefox, or set another browser to identify itself as Firefox, then the user agent passed by the browser will match the constraint and we&amp;rsquo;ll see the page.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/336/original/E203I05.png" width="973" height="287" alt="The route only matches when viewed in Firefox"/&gt;
&lt;/div&gt;

&lt;p&gt;We can also add a constraint for something a little more useful, say the host:&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/secret&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;, :constraints =&amp;gt; { :host =&amp;gt; /localhost/ }
&lt;/pre&gt;
&lt;p&gt;This constraint means that we can visit &lt;a href="http://localhost:3000/secret"&gt;http://localhost:3000/secret&lt;/a&gt; and see the page but we&amp;rsquo;ll get a routing error if we try to visit by using the IP address instead ( &lt;a href="http://127.0.0.1/secret"&gt;http://127.0.0.1/secret&lt;/a&gt; ) even though the two addresses are equivalent. This can be used to restrict certain routes to a given subdomain. This ability is currently a little clunky but in a future version of Rails we&amp;rsquo;ll be able to pass a &lt;code&gt;:subdomain&lt;/code&gt; option to perform this kind of constraint.&lt;/p&gt;

&lt;p&gt;If we have a number of routes that match a certain constraint there can be a lot of duplication in the routes file. We can reduce this duplication by using the constraints method and putting the matching routes into a block.&lt;/p&gt;
&lt;pre class="ruby"&gt;
constraints :host =&amp;gt; /localhost/ do
  match &amp;quot;/secret&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;
  match &amp;quot;/topsecret&amp;quot; =&amp;gt; &amp;quot;info#about&amp;quot;
end
&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s much more that can be done with the constraint option but we won&amp;rsquo;t cover it here.&lt;/p&gt;

&lt;h3&gt;Routing with Rack&lt;/h3&gt;

&lt;p&gt;There&amp;rsquo;s a lot more to routing in Rails 3 than we&amp;rsquo;ve had time to cover here, but we&amp;rsquo;ll be coming back to the topic of routing in future episodes. One last feature we&amp;rsquo;ll take a look at is how Rails 3 routing embraces Rack.  Normally we pass a controller and action name to a route but we can also pass in a Rack application which is an extremely powerful feature.   To demonstrate this we&amp;rsquo;ll create a route that points to a simple Rack application.&lt;/p&gt;
&lt;pre class="ruby"&gt;
match &amp;quot;/hello&amp;quot; =&amp;gt; proc { |env| [200, {}, &amp;quot;Hello Rack!&amp;quot;] }
&lt;/pre&gt;
&lt;p&gt;If you aren&amp;rsquo;t familiar with Rack then either &lt;a href="http://asciicasts.com/episodes/151-rack-middleware"&gt;watch&lt;/a&gt; or &lt;a href="http://asciicasts.com/episodes/151-rack-middleware"&gt;read&lt;/a&gt; episode 151. All we&amp;rsquo;re doing above is passing a return code, an (empty) hash of headers and a simple body.&lt;/p&gt;

&lt;p&gt;If we visit &lt;code&gt;/hello&lt;/code&gt; in the browser now we&amp;rsquo;ll see &amp;ldquo;Hello Rack!&amp;rdquo; so that we know our Rack application is working and generating the response. This opens up a lot of power and flexibility in how you define routes and route them to different applications. It&amp;rsquo;s easy now to route to a Sinatra application for example.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/337/original/E203I06.png" width="799" height="280" alt="The response is seen from the Rack app."/&gt;
&lt;/div&gt;

&lt;p&gt;Rails 3&amp;rsquo;s new routing features provide a number of exciting possibilities. Although we&amp;rsquo;ve only given an overview of the potential here we&amp;rsquo;ll be looking at certain parts of it in more detail in the future.&lt;/p&gt;

&lt;p&gt;For more documentation there is more information about Rails 3 routing on &lt;a href="http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/"&gt;Yehuda Katz&amp;rsquo;s blog&lt;/a&gt; and on &lt;a href="http://guides.rails.info/routing.html"&gt;RailsGuides&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Fri, 05 Mar 2010 22:23:27 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/203-routing-in-rails-3</guid>
      <link>http://asciicasts.com/episodes/203-routing-in-rails-3</link>
    </item>
    <item>
      <title>Active Record Queries in Rails 3</title>
      <description>&lt;p&gt;Over the last two episodes we&amp;rsquo;ve shown you how to set up your computer for Rails 3 and create new Rails 3 applications. In this episode we&amp;rsquo;ll begin looking at some of its new features, starting with ActiveRecord which provides a new interface for performing database queries. Pratik Naik went into this subject in detail in &lt;a href="http://m.onkey.org/2010/1/22/active-record-query-interface"&gt;a post on his blog&lt;/a&gt; recently which is well worth reading.&lt;/p&gt; 

&lt;h3&gt;Some Basic Examples&lt;/h3&gt;

&lt;p&gt;To start we&amp;rsquo;ll show you a few examples of old ActiveRecord find calls and convert them into the new query format. For this we&amp;rsquo;ll be using a basic Rails application that has two models: &lt;code&gt;Article&lt;/code&gt; and &lt;code&gt;Comment&lt;/code&gt; that have a relationship whereby an &lt;code&gt;Article&lt;/code&gt; &lt;code&gt;has_many :comments&lt;/code&gt;.&lt;/p&gt;  

&lt;p&gt;The first find we&amp;rsquo;ll update returns the ten most recently published articles.&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.find(:all, :order =&amp;gt; &amp;quot;published_at desc&amp;quot;, :limit =&amp;gt; 10)
&lt;/pre&gt;
&lt;p&gt;The basic approach to converting an ActiveRecord query to the new Rails 3 format is to look at the hash of options that&amp;rsquo;s being passed to &lt;code&gt;find&lt;/code&gt; and to replace each item in the hash with an equivalent method. So, instead of the find call above we can use:&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.order(&amp;quot;published_at desc&amp;quot;).limit(10)
&lt;/pre&gt;
&lt;p&gt;As you can see the new syntax is easy to convert from the old Rails find but has a neater syntax.&lt;/p&gt;

&lt;p&gt;The old hash options don&amp;rsquo;t always map exactly onto the new methods however as we&amp;rsquo;ll demonstrate in this next example.&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.find(:all, :conditions =&amp;gt; [&amp;quot;published_at &amp;lt;= ?&amp;quot;, Time.now], :include =&amp;gt; :comments)
&lt;/pre&gt;
&lt;p&gt;There are only two real exceptions to the rule and conveniently the example above uses them both. The find above will get all of the articles that have a published date before the current time along with any associated comments. In Rails 3 this becomes:&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.where(&amp;quot;published_at &amp;lt;= ?&amp;quot;, Time.now).includes(:comments)
&lt;/pre&gt;
&lt;p&gt;Instead of &lt;code&gt;:conditions&lt;/code&gt; we now use the &lt;code&gt;where&lt;/code&gt; method, passing in the same arguments as we would to &lt;code&gt;:conditions&lt;/code&gt;. The arguments can be passed as an array but it&amp;rsquo;s cleaner to pass them separately. For getting associated records &lt;code&gt;:include&lt;/code&gt; gets pluralized to become the &lt;code&gt;includes&lt;/code&gt; method. All of the other options we&amp;rsquo;d normally pass to &lt;code&gt;find&lt;/code&gt; become methods with the same name as the option.&lt;/p&gt;
 
&lt;p&gt;Our final example fetches the most recently published article.&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.find(:first, :order =&amp;gt; &amp;quot;published_at desc&amp;quot;)
&lt;/pre&gt;
&lt;p&gt;Using the Rails 3 syntax this becomes:&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.order(&amp;quot;published_at desc&amp;quot;).first()
&lt;/pre&gt;
&lt;p&gt;Note that we don&amp;rsquo;t call &lt;code&gt;first&lt;/code&gt; until the end of the method chain.&lt;/p&gt; 

&lt;p&gt;As we&amp;rsquo;re fetching in descending order we could rewrite the line above as:&lt;/p&gt;
&lt;pre class="ruby"&gt;
Article.order(&amp;quot;published_at&amp;quot;).last()
&lt;/pre&gt;
&lt;p&gt;This will perform the same query but with slightly more concise code.&lt;/p&gt;

&lt;p&gt;In Rails 3.0 we can use either the old &lt;code&gt;find&lt;/code&gt; methods or the new Rails 3 syntax but in Rails 3.1 the old methods will be deprecated and from Rails 3.2 they will be removed completely. It&amp;rsquo;s well worth rewriting your finds as you migrate your applications to Rails 3 so that your applications will be compatible with future releases of Rails 3.&lt;/p&gt;

&lt;p&gt;You might be wondering at this point just what the point of this new syntax is, especially as it will break a lot of existing Rails applications when they are upgraded. Well there is a purpose to this change and it lies in the power of lazy loading.&lt;/p&gt; 

&lt;h3&gt;Lazy Loading&lt;/h3&gt;

&lt;p&gt;To demonstrate lazy loading we&amp;rsquo;ll use our application&amp;rsquo;s console. If we ask for all of the articles we&amp;rsquo;ll get an array returned as we&amp;rsquo;d expect and we&amp;rsquo;ll see that we have three articles in our database.&lt;/p&gt;
&lt;pre class="terminal"&gt;
ruby-1.9.1-p378 &amp;gt; Article.all =&amp;gt; [#&amp;lt;Article id: 1, name: &amp;quot;It&amp;#x27;s Ancient&amp;quot;, published_at: nil, hidden: false, 
created_at: &amp;quot;2010-02-22 20:35:42&amp;quot;, updated_at: &amp;quot;2010-02-22 20:35:42&amp;quot;&amp;gt;, 
#&amp;lt;Article id: 2, name: &amp;quot;Can&amp;#x27;t See Me&amp;quot;, published_at: nil, hidden: false, 
created_at: &amp;quot;2010-02-22 20:37:03&amp;quot;, updated_at: &amp;quot;2010-02-22 20:37:03&amp;quot;&amp;gt;, 
#&amp;lt;Article id: 3, name: &amp;quot;To the Future!&amp;quot;, published_at: nil, hidden: false, 
created_at: &amp;quot;2010-02-22 20:38:17&amp;quot;, updated_at: &amp;quot;2010-02-22 20:38:17&amp;quot;&amp;gt;]
&lt;/pre&gt; 
&lt;p&gt;If we want to get all of the articles in alphabetical order we can do so by using the order method:&lt;/p&gt;
&lt;pre class="terminal"&gt;
ruby-1.9.1-p378 &amp;gt; articles = Article.order(&amp;quot;name&amp;quot;)
 =&amp;gt; #&amp;lt;ActiveRecord::Relation:0x00000101669b90 @table=#&amp;lt;Arel::Table:0x000001023e9af8 
@name=&amp;quot;articles&amp;quot;, @options={:engine=&amp;gt;#&amp;lt;Arel::Sql::Engine:0x000001023a15c8 @ar=ActiveRecord::Base,
@adapter_name=&amp;quot;SQLite&amp;quot;&amp;gt;}, @engine=#&amp;lt;Arel::Sql::Engine:0x000001023a15c8 @ar=ActiveRecord::Base,
@adapter_name=&amp;quot;SQLite&amp;quot;&amp;gt;, &amp;hellip;
&lt;/pre&gt; 
&lt;p&gt;Instead of a list of articles being returned this time we have an &lt;code&gt;ActiveRecord::Relation&lt;/code&gt; object. This object stores information about our find, but the database query hasn&amp;rsquo;t yet been made. This is what is meant by lazy loading in this context: the data isn&amp;rsquo;t loaded until it has to be. If we were to enumerate through the records with &lt;code&gt;each&lt;/code&gt; or get all or just the first of the articles then the query will be made.&lt;/p&gt;
&lt;pre class="terminal"&gt;
ruby-1.9.1-p378 &amp;gt; articles.first
 =&amp;gt; #&amp;lt;Article id: 2, name: &amp;quot;Can&amp;#x27;t See Me&amp;quot;, published_at: nil, hidden: false, 
created_at: &amp;quot;2010-02-22 20:37:03&amp;quot;, updated_at: &amp;quot;2010-02-22 20:37:03&amp;quot;&amp;gt;
&lt;/pre&gt; 
&lt;p&gt;Now let&amp;rsquo;s see how this applies to our application. We&amp;rsquo;ve generated a scaffold for the article model so we have an articles controller with the usual seven actions. The code for the &lt;code&gt;index&lt;/code&gt; action uses &lt;code&gt;Article.all&lt;/code&gt; to get all of the articles immediately:&lt;/p&gt;

&lt;pre class="codeFilePath"&gt;/app/controllers/articles_controller.rb&lt;/pre&gt;
&lt;pre class="ruby"&gt;
def index
  @articles = Article.all

  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml =&amp;gt; @articles }
  end
end
&lt;/pre&gt;
&lt;p&gt;If we use use any of the find options on the articles, such as ordering by name then an &lt;code&gt;ActiveRecord::Relation&lt;/code&gt; object will be returned instead and the query will not be performed in the controller. The database query will instead be performed in the view code when we enumerate through each &lt;code&gt;Article&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="codeFilePath"&gt;/app/views/articles/index.html.erb&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% @articles.each do |article| %&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;%= article.name %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;%= article.published_at %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;%= article.hidden %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;#x27;Show&amp;#x27;, article %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;#x27;Edit&amp;#x27;, edit_article_path(article) %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;#x27;Destroy&amp;#x27;, article, :confirm =&amp;gt; &amp;#x27;Are you sure?&amp;#x27;, :method =&amp;gt; :delete %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If we load the index page now the articles will be shown in alphabetical order.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/329/original/E202I01.png" width="798" height="368" alt="The scaffold-generated article index page."/&gt;
&lt;/div&gt;

&lt;p&gt;The nice thing about this is that if you&amp;rsquo;re using fragment caching with the &lt;code&gt;cache&lt;/code&gt; method in your view this will now work better as the database query will not be performed unless it is necessary.&lt;/p&gt;

&lt;p&gt;The new query syntax makes it easier to build up find conditions. Let&amp;rsquo;s say we want to filter the articles so that only the hidden ones are shown if we have &lt;code&gt;hidden=1&lt;/code&gt; in the URL&amp;rsquo;s query string. We can do that by modifying the &lt;code&gt;index&lt;/code&gt; action like this:&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;/app/controllers/articles_controller.rb&lt;/pre&gt;
&lt;pre class="ruby"&gt;
def index
  @articles = Article.order(&amp;#x27;name&amp;#x27;)
    
  if params[:hidden]
    @articles = @articles.where(:hidden =&amp;gt;(params[:hidden] == &amp;quot;1&amp;quot;))
  end

  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml =&amp;gt; @articles }
  end
end
&lt;/pre&gt;
&lt;p&gt;Now we check that the there is a &lt;code&gt;hidden&lt;/code&gt; parameter passed and if there is we add a &lt;code&gt;where&lt;/code&gt; method to the find that will show only the hidden articles if that hidden parameter has a value of &lt;code&gt;1&lt;/code&gt;. If we append that parameter to the URL and reload the page we&amp;rsquo;ll see just the hidden articles.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/330/original/E202I02.png" width="796" height="280" alt="Showing just the hidden articles."/&gt;
&lt;/div&gt;

&lt;p&gt;Likewise if we pass &lt;code&gt;0&lt;/code&gt; we&amp;rsquo;ll see only the visible articles.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/331/original/E202I03.png" width="796" height="280" alt="Now only the visible articles are shown."/&gt;
&lt;/div&gt;

&lt;p&gt;Being able to chain together methods like this is a nice way to be able to build up more complex database queries while knowing that the query won&amp;rsquo;t actually be executed until the data is needed.&lt;/p&gt;

&lt;h3&gt;Named Scopes&lt;/h3&gt;

&lt;p&gt;Next we&amp;rsquo;ll show you some of the changes to named scopes in Rails 3. Below is our &lt;code&gt;Article&lt;/code&gt; model with two named scopes, one to fetch the visible articles and one to fetch the articles that have been published.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;/app/models/article.rb&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Article &amp;lt; ActiveRecord::Base
  named_scope :visible, :conditions =&amp;gt; [&amp;quot;hidden != ?&amp;quot;, true]
  named_scope :published, lambda { {:conditions =&amp;gt; [&amp;quot;published_at &amp;lt;= ?&amp;quot;, Time.zone.now]} }
end
&lt;/pre&gt;
&lt;p&gt;These named scopes are defined as we&amp;rsquo;d define them in a Rails 2 application but the Rails 3 approach is a little different. The first difference is that the method to define a named scope is no longer &lt;code&gt;named_scope&lt;/code&gt; but just &lt;code&gt;scope&lt;/code&gt;. Also we no longer pass the conditions as a hash but, as with find, we use now use methods. Like we did with the new find methods we use &lt;code&gt;where&lt;/code&gt; instead of &lt;code&gt;:conditions&lt;/code&gt;. In the Rails 3 syntax the named scopes will look like this:&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;/app/models/article.rb&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Article &amp;lt; ActiveRecord::Base
  scope :visible, where(&amp;quot;hidden != ?&amp;quot;, true)
  scope :published, lambda { where(&amp;quot;published_at &amp;lt;= ?&amp;quot;, Time.zone.now) }
end
&lt;/pre&gt;
&lt;p&gt;Another new feature is the ability to build up scopes. If we want to create a scope called &lt;code&gt;recent&lt;/code&gt; that will return the recently published visible articles ordered by their publish date we can do so by reusing the two scopes we already have.&lt;/p&gt;
&lt;pre class="ruby"&gt;
scope :recent, visible.published.order(&amp;quot;published_at desc&amp;quot;)
&lt;/pre&gt;
&lt;p&gt;What we&amp;rsquo;ve done in our new scope is chain together the two scopes we already have an add an &lt;code&gt;order&lt;/code&gt; method to create a new scope and this chaining ability is a very powerful feature to have when creating scopes for our models.&lt;/p&gt;

&lt;p&gt;We can try our new named scope in the console. If we call &lt;code&gt;Article.recent&lt;/code&gt; an &lt;code&gt;ActiveRecord::NamedScope::Scope&lt;/code&gt; object is returned. This is an object that behaves in a similar way to the &lt;code&gt;ActiveRecord::Relation&lt;/code&gt; object we saw earlier.&lt;/p&gt;
&lt;pre class="terminal"&gt;
ruby-1.9.1-p378 &amp;gt; Article.recent
 =&amp;gt; #&amp;lt;ActiveRecord::NamedScope::Scope:0x0000010318bd08 @table=#&amp;lt;Arel::Table:0x00000102740ea8 
 @name=&amp;quot;articles&amp;quot;, @options={:engine=&amp;gt;#&amp;lt;Arel::Sql::Engine:0x00000102651900 @ar=ActiveRecord::Base&amp;gt;}, 
 @engine=#&amp;lt;Arel::Sql::Engine:0x00000102651900 @ar=ActiveRecord::Base&amp;gt;&amp;gt;, &amp;hellip;
&lt;/pre&gt;
&lt;p&gt;If we call &lt;code&gt;all&lt;/code&gt; on the &lt;code&gt;Scope&lt;/code&gt; object then we&amp;rsquo;ll see the matching article returned.&lt;/p&gt;
&lt;pre class="terminal"&gt;
ruby-1.9.1-p378 &amp;gt; Article.recent.all
 =&amp;gt; [#&amp;lt;Article id: 1, name: &amp;quot;It&amp;#x27;s Ancient&amp;quot;, published_at: &amp;quot;2010-01-01&amp;quot;, 
 hidden: false, created_at: &amp;quot;2010-02-22 20:35:42&amp;quot;, updated_at: &amp;quot;2010-02-22 23:00:16&amp;quot;&amp;gt;]
&lt;/pre&gt;

&lt;h3&gt;A Final Tip&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll round up this episode with a useful tip. If you have a &lt;code&gt;Relation&lt;/code&gt; or &lt;code&gt;Scope&lt;/code&gt; object and want to see the SQL query that it would run against the database you can call &lt;code&gt;to_sql&lt;/code&gt; on it.&lt;/p&gt;
&lt;pre class="terminal"&gt;
ruby-1.9.1-p378 &amp;gt; Article.recent.to_sql
 =&amp;gt; &amp;quot;SELECT     \&amp;quot;articles\&amp;quot;.* FROM       \&amp;quot;articles\&amp;quot; 
 WHERE     (hidden != &amp;#x27;t&amp;#x27;) AND (published_at &amp;lt;= &amp;#x27;2010-02-22 22:47:12.023289&amp;#x27;) 
 ORDER BY  published_at desc&amp;quot;
&lt;/pre&gt; 
&lt;p&gt;This shows the SQL that ActiveRecord will perform to return the recently published articles that are not hidden.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it for this episode on using ActiveRecord queries in Rails 3. There are a lot of great additions that will make the code in your Rails controllers more concise and expressive. Any time spent playing with the new features will soon repay itself.&lt;/p&gt;</description>
      <pubDate>Tue, 23 Feb 2010 19:55:05 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/202-active-record-queries-in-rails-3</guid>
      <link>http://asciicasts.com/episodes/202-active-record-queries-in-rails-3</link>
    </item>
    <item>
      <title>Bundler</title>
      <description>&lt;p&gt;In this episode we&amp;rsquo;ll continue our look at the new features of Rails 3. This time we&amp;rsquo;re going to take a look at &lt;a href="http://github.com/carlhuda/bundler"&gt;bundler&lt;/a&gt; which is the new way to manage gem dependencies in Rails applications.&lt;/p&gt;

&lt;p&gt;Bundler is currently being updated fairly often so before doing anything with it it&amp;rsquo;s worth making sure that you have the latest version by running&lt;/p&gt;
&lt;pre class="terminal"&gt;
gem install bundler
&lt;/pre&gt;
&lt;p&gt;Note that we&amp;rsquo;re not using &lt;code&gt;sudo&lt;/code&gt; when we install the gem because we&amp;rsquo;re using a version of Ruby that we installed with rvm.&lt;/p&gt;

&lt;h3&gt;Using Bunder to Install Gems&lt;/h3&gt;

&lt;p&gt;In the previous episode when we tried to start up the web server for the application it complained about a missing sqlite3-ruby gem. We resolved this by manually installing the gem with &lt;code&gt;gem install&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
gem install sqlite3-ruby
&lt;/pre&gt;
&lt;p&gt;We could instead do this through bundler as sqlite3-ruby is a bundler dependency for our application, i.e. it is listed in the application&amp;rsquo;s &lt;code&gt;Gemfile&lt;/code&gt;. To do that we run &lt;code&gt;bundle install&lt;/code&gt; which will go through the application&amp;rsquo;s gem dependencies and install them.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ bundle install
Fetching source index from http://gemcutter.org
Resolving dependencies
Installing abstract (1.0.0) from system gems 
Installing actionmailer (3.0.0.beta) from system gems 
Installing actionpack (3.0.0.beta) from system gems 
Installing activemodel (3.0.0.beta) from system gems 
Installing activerecord (3.0.0.beta) from system gems 
Installing activeresource (3.0.0.beta) from system gems 
Installing activesupport (3.0.0.beta) from system gems 
Installing arel (0.2.1) from rubygems repository at http://gemcutter.org 
Installing builder (2.1.2) from system gems 
Installing bundler (0.9.5) from system gems 
Installing erubis (2.6.5) from system gems 
Installing i18n (0.3.3) from system gems 
Installing mail (2.1.2) from system gems 
Installing memcache-client (1.7.8) from system gems 
Installing mime-types (1.16) from system gems 
Installing rack (1.1.0) from system gems 
Installing rack-mount (0.4.7) from rubygems repository at http://gemcutter.org 
Installing rack-test (0.5.3) from system gems 
Installing rails (3.0.0.beta) from system gems 
Installing railties (3.0.0.beta) from system gems 
Installing rake (0.8.7) from system gems 
Installing sqlite3-ruby (1.2.5) from system gems 
Installing text-format (1.0.0) from system gems 
Installing text-hyphen (1.0.0) from system gems 
Installing thor (0.13.1) from rubygems repository at http://gemcutter.org 
Installing tzinfo (0.3.16) from system gems 
Your bundle is complete!
&lt;/pre&gt;
&lt;p&gt;We can see from the output above that bundler has installed all of the gems that the application needs, including sqlite3-ruby. Had it not been already installed then bundler would have downloaded it from Gemcutter and installed it.&lt;/p&gt;

&lt;p&gt;So, when in doubt, run &lt;code&gt;bundle install&lt;/code&gt;. You should do this whenever you create a new Rails application or clone someone else&amp;rsquo;s application so that you ensure that you have the correct gems installed. You should also run it when you deploy an application so that the correct gems are installed on the server. You can even add it to your deployment recipe so that it always runs whenever your application is deployed.&lt;/p&gt;

&lt;p&gt;One important thing to note is that you should never run &lt;code&gt;sudo&lt;/code&gt; when running &lt;code&gt;bundle install&lt;/code&gt;, even if you usually use &lt;code&gt;sudo&lt;/code&gt; when installing gems.&lt;/p&gt;

&lt;h3&gt;Adding Gem Dependencies&lt;/h3&gt;

&lt;p&gt;Now that we know how to manage our gems how do we install and add new gem dependencies to our application? In earlier version of Rails we&amp;rsquo;d manage these in our application&amp;rsquo;s &lt;code&gt;/config/environment.rb&lt;/code&gt; file, but in Rails 3 gem configuration belongs in a file called &lt;code&gt;Gemfile&lt;/code&gt; in the application&amp;rsquo;s root directory. The default Gemfile looks like this:&lt;/p&gt;
&lt;pre class="ruby"&gt;
# Edit this Gemfile to bundle your application&amp;#x27;s dependencies.
source &amp;#x27;http://gemcutter.org&amp;#x27;


gem &amp;quot;rails&amp;quot;, &amp;quot;3.0.0.beta&amp;quot;

## Bundle edge rails:
# gem &amp;quot;rails&amp;quot;, :git =&amp;gt; &amp;quot;git://github.com/rails/rails.git&amp;quot;

# ActiveRecord requires a database adapter. By default,
# Rails has selected sqlite3.
gem &amp;quot;sqlite3-ruby&amp;quot;, :require =&amp;gt; &amp;quot;sqlite3&amp;quot;

## Bundle the gems you use:
# gem &amp;quot;bj&amp;quot;
# gem &amp;quot;hpricot&amp;quot;, &amp;quot;0.6&amp;quot;
# gem &amp;quot;sqlite3-ruby&amp;quot;, :require =&amp;gt; &amp;quot;sqlite3&amp;quot;
# gem &amp;quot;aws-s3&amp;quot;, :require =&amp;gt; &amp;quot;aws/s3&amp;quot;

## Bundle gems used only in certain environments:
# gem &amp;quot;rspec&amp;quot;, :group =&amp;gt; :test
# group :test do
#   gem &amp;quot;webrat&amp;quot;
# end
&lt;/pre&gt;
&lt;p&gt;There are a couple of gems already included in the file, including &lt;code&gt;rails&lt;/code&gt; and &lt;code&gt;sqlite3-ruby&lt;/code&gt;. Note that the line that references the &lt;code&gt;rails&lt;/code&gt; gem includes a version number. With any gem reference in this file we can specify a version number so that we can include a certain version of a gem. If we want to upgrade the Rails version at some point we can change the version here rather than in the &lt;code&gt;environment.rb&lt;/code&gt; file.&lt;/p&gt; 

&lt;p&gt;If we want to use any additional gems in our application we can just add them to this file. For example, if we want to use will_paginate we can reference it like this:&lt;/p&gt;
&lt;pre class="ruby"&gt;
gem &amp;quot;will_paginate&amp;quot;, &amp;quot;&amp;gt;=2.3.12&amp;quot;
&lt;/pre&gt;
&lt;p&gt;The second parameter is a version number and used here it will mean that bundler will install version 2.3.12 or any newer version that it finds. Once we&amp;rsquo;ve added the gem reference we can install it with &lt;code&gt;bundle install&lt;/code&gt;, but before we do that we&amp;rsquo;ll demonstrate another bundle command: &lt;code&gt;bundle check&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can run &lt;code&gt;bundle check&lt;/code&gt; to list the gems that our application depends on but which aren&amp;rsquo;t installed. If we run it for our application it will show that will_paginate gem that we&amp;rsquo;ve referenced but not yet installed.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ bundle check
The following dependencies are missing
  * will_paginate (&amp;gt;= 2.3.12, runtime)We can install the missing gems by running bundle install again. 
&lt;/pre&gt;
&lt;p&gt;To see what other bundle commands are available we can run &lt;code&gt;bundle help&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ bundle help
Tasks:
  bundle check        # Checks if the dependencies listed in Gemfile are satisfied by currently installed gems
  bundle exec         # Run the command in context of the bundle
  bundle help [TASK]  # Describe available tasks or one specific task
  bundle init         # Generates a Gemfile into the current working directory
  bundle install      # Install the current environment to the system
  bundle lock         # Locks the bundle to the current set of dependencies, including all child dependencies.
  bundle pack         # Packs all the gems to vendor/cache
  bundle show         # Shows all gems that are part of the bundle.
  bundle unlock       # Unlock the bundle. This allows gem versions to be changed
&lt;/pre&gt;
&lt;h3&gt;Other Gemfile Options&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll go back to our Gemfile now to see what else we can do in it. One cool new feature is the ability to get a gem from a git repository. For example, if we want to live of the edge and use the latest version of Rails in our application we can point the Rails gem to its Git repository.&lt;/p&gt;
&lt;pre class="ruby"&gt;
# Bundle edge rails:
gem &amp;quot;rails&amp;quot;, :git =&amp;gt; &amp;quot;git://github.com/rails/rails.git&amp;quot;
&lt;/pre&gt;
&lt;p&gt;This is a powerful feature to have. If a gem doesn&amp;rsquo;t quite work as we want it to we can fork the project on Github, modify the code to suit and then point the gem dependency to point to our version.&lt;/p&gt;

&lt;p&gt;We can also restrict gems to a certain environment. If we want to use RSpec for testing we can pass in a &lt;code&gt;:group&lt;/code&gt; option to restrict it to the test environment.&lt;/p&gt;
&lt;pre class="ruby"&gt;
gem &amp;quot;rspec&amp;quot;, :group =&amp;gt; :test
&lt;/pre&gt;
&lt;p&gt;Alternatively, if we have a number of gems we want to restrict to one environment we can use &lt;code&gt;group&lt;/code&gt; and pass it a block.&lt;/p&gt;
&lt;pre class="ruby"&gt;
group :test do
  gem &amp;quot;webrat&amp;quot;
  get &amp;quot;rspec&amp;quot;
end
&lt;/pre&gt;
&lt;p&gt;If we run &lt;code&gt;bundle install&lt;/code&gt; now it will install all of the gems we&amp;rsquo;ve specified for each environment.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ bundle install
Fetching source index from http://gemcutter.org
Resolving dependencies
...
Installing rspec (1.3.0) from rubygems repository at http://gemcutter.org 
...
Installing webrat (0.7.0) from rubygems repository at http://gemcutter.org 
Installing will_paginate (2.3.12) from system gems 
Your bundle is complete!
&lt;/pre&gt;
&lt;p&gt;As you&amp;rsquo;ll see from the (truncated) output above we can see that that two gems we specified in our &lt;code&gt;Gemfile&lt;/code&gt; have been installed.&lt;/p&gt; 

&lt;p&gt;If we want to install gems but exclude those from a certain environment we can use the &lt;code&gt;--without&lt;/code&gt; option. To install the gems that aren&amp;rsquo;t in the test group we can run:&lt;/p&gt;
&lt;pre class="terminal"&gt;
bundle install --without=test
&lt;/pre&gt;
&lt;p&gt;This is useful when you&amp;rsquo;re installing your application on your production server and don&amp;rsquo;t want to install the gems that are only used in the test environment.&lt;/p&gt;

&lt;h3&gt;Locking Gems&lt;/h3&gt;

&lt;p&gt;Another useful command is &lt;code&gt;bundle lock&lt;/code&gt;. This locks down the specific versions of the gems your application is using. After we run it our project will have a new file in it called &lt;code&gt;Gemfile.lock&lt;/code&gt;. This file lists all of the gems that are installed for our application along with specific version that is used. After running &lt;code&gt;bundle lock&lt;/code&gt; only the specific versions listed in the &lt;code&gt;Gemfile.lock&lt;/code&gt; file will be installed when we run &lt;code&gt;bundle install&lt;/code&gt;, even if there are never versions available.&lt;/p&gt;

&lt;p&gt;You might be wondering when you&amp;rsquo;d want to use &lt;code&gt;bundle lock&lt;/code&gt;. Well, it&amp;rsquo;s worth using whenever a project is used in other locations. If we&amp;rsquo;re working with other Rails developers on a project we can use bundle lock to ensure that everyone is using the same versions of the gems that the application uses. The same applies when the application is being deployed to production. As the application will be being deployed to a different server we&amp;rsquo;ll want to be sure that exactly the same versions are used on the production server as they are on our development machine.&lt;/p&gt;

&lt;p&gt;If we do need to make changes to an application&amp;rsquo;s gems after running &lt;code&gt;bundle lock&lt;/code&gt; we shouldn&amp;rsquo;t change the &lt;code&gt;Gemfile.lock&lt;/code&gt; file directly. Instead we should update the &lt;code&gt;Gemfile&lt;/code&gt; as we did before. Once we&amp;rsquo;ve made our changes to the &lt;code&gt;Gemfile&lt;/code&gt;, however, running &lt;code&gt;bundle install&lt;/code&gt; won&amp;rsquo;t update the application&amp;rsquo;s gems as the gemfile is locked. To update the gems we need to pass the &lt;code&gt;--relock&lt;/code&gt; option.&lt;/p&gt;
&lt;pre class="terminal"&gt;
bundle install --relock
&lt;/pre&gt;
&lt;p&gt;This will unlock the gemfile, update the gems and then re-lock.&lt;/p&gt;

&lt;h3&gt;Packing Gems With An Application&lt;/h3&gt;

&lt;p&gt;That pretty much covers the basic bundler workflow and is enough to cover most of what you&amp;rsquo;ll need when working with bundler in your applications. One final bundler feature we&amp;rsquo;ll cover is &lt;code&gt;bundle pack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bundler installs the gems in a &lt;code&gt;.bundle&lt;/code&gt; directory under our home directory.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ ls ~/.bundle
cache		doc		gems		ruby		specifications
&lt;/pre&gt;
&lt;p&gt;This means that the gems aren&amp;rsquo;t bundled with our application and aren&amp;rsquo;t included in our project&amp;rsquo;s version control system. If we want to store the gems within our application we can run &lt;code&gt;bundle pack&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
bundle pack
Copying .gem files into vendor/cache
  * memcache-client-1.7.8.gem
  * rspec-1.3.0.gem
  * thor-0.13.3.gem
  * tzinfo-0.3.16.gem
  * builder-2.1.2.gem
  * nokogiri-1.4.1.gem
  * mime-types-1.16.gem
  * sqlite3-ruby-1.2.5.gem
  * i18n-0.3.3.gem
  * abstract-1.0.0.gem
  * erubis-2.6.5.gem
  * text-hyphen-1.0.0.gem
  * bundler-0.9.6.gem
  * rake-0.8.7.gem
  * will_paginate-2.3.12.gem
  * text-format-1.0.0.gem
  * rack-1.1.0.gem
  * rack-test-0.5.3.gem
  * webrat-0.7.0.gem
  * rack-mount-0.4.7.gem
  * activesupport-3.0.0.beta.gem
  * mail-2.1.2.gem
  * arel-0.2.1.gem
  * activemodel-3.0.0.beta.gem
  * actionpack-3.0.0.beta.gem
  * actionmailer-3.0.0.beta.gem
  * activerecord-3.0.0.beta.gem
  * activeresource-3.0.0.beta.gem
  * railties-3.0.0.beta.gem
  * rails-3.0.0.beta.gem
&lt;/pre&gt;  
&lt;p&gt;This will generate the &lt;code&gt;.gem&lt;/code&gt; files your application that our application needs and copy them to its &lt;code&gt;/vendor/cache&lt;/code&gt; directory, creating the directory if necessary. The gems will now be installed directly from these &lt;code&gt;.gem&lt;/code&gt; files instead of being fetched remotely from, for example, Gemcutter.&lt;/p&gt;

&lt;p&gt;This shouldn&amp;rsquo;t be something you&amp;rsquo;ll need very often but if you&amp;rsquo;re in a situation where you don&amp;rsquo;t want your production server to connect to Gemcutter to download the gems from there then this is a good way to go.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it for this episode. I hope it gave you a good overview on how to use bundler to manage the gems in your applications. Bundler may take a little getting used to but in the long run it will save you from some of the problems that you may have had with gem dependencies in the past.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll finish by encouraging you to visit &lt;a href="http://railsplugins.org/"&gt;railsplugins.org&lt;/a&gt;. You&amp;rsquo;re probably wondering which gems and plugins work with Rails 3 and this is the place to find out. On the site you can browse the plugins and see if they work with Rails 3 and Ruby 1.9.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/328/original/E201I01.png" width="767" height="634" alt="The RailsPlugins website." /&gt;
&lt;/div&gt;

&lt;p&gt;If a gem you want to use in a Rails 3 application is listed as not working or untested then this is a great opportunity to raise issues or help to fix it. This way you can help to get involved in getting as many gems and plugins working with Rails 3.&lt;/p&gt;</description>
      <pubDate>Thu, 18 Feb 2010 21:30:05 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/201-bundler</guid>
      <link>http://asciicasts.com/episodes/201-bundler</link>
    </item>
    <item>
      <title>Rails 3 Beta and RVM</title>
      <description>&lt;p&gt;What better way to celebrate episode 200 than with a first look at Rails 3? The first beta version of Rails 3.0 has just been released and in this episode we&amp;rsquo;ll show you how to get it installed and set up. Then over the next few episodes we&amp;rsquo;ll cover the new features in depth. Even if you don&amp;rsquo;t plan on upgrading any of your applications soon it&amp;rsquo;s still worth installing the beta so that you can get your feet wet with it and play with some of the new features.&lt;/p&gt; 

&lt;h3&gt;Updating Ruby&lt;/h3&gt;

&lt;p&gt;Rails 3 needs Ruby 1.8.7 or later to run, so the first thing to do is to see which version you currently have by running &lt;code&gt;ruby -v&lt;/code&gt; in a terminal window.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ ruby -v
ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
&lt;/pre&gt;
&lt;p&gt;This machine is running Ruby 1.8.6 so we&amp;rsquo;ll need to upgrade Ruby before we can go any further. We could do this manually but instead we&amp;rsquo;re going to use rvm, the &lt;a href="http://rvm.beginrescueend.com"&gt;Ruby Version Manager&lt;/a&gt;. This allows us to install different versions of Ruby easily and switch between them with just a single command.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;re running Windows then rvm isn&amp;rsquo;t available and you will have to install Ruby manually. On Linux, OS X or other UNIX-based operating systems we can install rvm by following the instructions on &lt;a href="http://rvm.beginrescueend.com/install/"&gt;the installation page&lt;/a&gt; and running the following command:&lt;/p&gt;
&lt;pre class="terminal"&gt;
mkdir -p ~/.rvm/src/ &amp;amp;&amp;amp; cd ~/.rvm/src &amp;amp;&amp;amp; rm -rf ./rvm/ &amp;amp;&amp;amp; git clone git://github.com/wayneeseguin/rvm.git &amp;amp;&amp;amp; cd rvm &amp;amp;&amp;amp; ./install
&lt;/pre&gt;
&lt;p&gt;After the command has finished running we&amp;rsquo;ll be given some instructions to finish the installation off. These instructions will differ depending on whether we&amp;rsquo;re running bash or zsh. Once we&amp;rsquo;ve followed those instructions and made the relevant changes we&amp;rsquo;ll need to close and reopen the terminal. We can then run the &lt;code&gt;rvm&lt;/code&gt; command to install any version of Ruby we want.&lt;/p&gt;

&lt;p&gt;Rails 3.0 needs Ruby 1.8.7 to run but it will also work under 1.9.1 and as we&amp;rsquo;re feeling adventurous we&amp;rsquo;ll install that version instead. To do this we run:&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rvm install 1.9.1
&lt;/pre&gt;
&lt;p&gt;This will download, configure and install Ruby 1.9.1 which will take a few minutes to do and it will keep your lap warm while it does it if you&amp;rsquo;re installing on a laptop. When it finishes we can type &lt;code&gt;rvm list&lt;/code&gt; to see which versions of Ruby we have installed.&lt;/p&gt;
&lt;pre class="terminal"&gt;
noonoo:~ eifion$ rvm list

   ruby-1.9.1-p378 [ x86_64 ]
   system [ x86_64 i386 ppc ]
&lt;/pre&gt;
&lt;p&gt;As we now have Ruby 1.9.1 as an installed version we can switch to it to make it the active version.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rvm 1.9.1
$ ruby -v
ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-darwin10.2.0]
&lt;/pre&gt;
&lt;p&gt;The new Ruby version will only be active for as long as we have a terminal window open. If we close and reopen the terminal we&amp;rsquo;ll be back to the default version of Ruby. To make the new version &amp;lsquo;stick&amp;rsquo; we can pass the &lt;code&gt;--default&lt;/code&gt; parameter to &lt;code&gt;rvm&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rvm 1.9.1 --default
$ ruby -v
ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-darwin10.2.0]
&lt;/pre&gt;
&lt;p&gt;Now we can open as many new shells as we like and 1.9.1 will be the Ruby version each time.&lt;/p&gt;

&lt;p&gt;If at any time we want to revert to the system version of Ruby we can use &lt;code&gt;rvm system&lt;/code&gt;, passing &lt;code&gt;--default&lt;/code&gt; if we want to permanently revert to the system-installed Ruby.&lt;/p&gt;

&lt;h3&gt;Installing The Rails Beta&lt;/h3&gt;

&lt;p&gt;Now that we have a supported version of Ruby installed we can install the Rails 3 beta. To do so we need to run these two lines from the Ruby on Rails Weblog3 in the console.&lt;/p&gt;
&lt;pre class="terminal"&gt;
gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
gem install rails --pre
&lt;/pre&gt;
&lt;p&gt;Because we&amp;rsquo;re installing a pre-release version of Rails we have to install the prerequisites separately which is what the first line above will do for us. Note that we&amp;rsquo;re not prefixing the &lt;code&gt;gem&lt;/code&gt; command with &lt;code&gt;sudo&lt;/code&gt;. As we&amp;rsquo;re using rvm we don&amp;rsquo;t want to use &lt;code&gt;sudo&lt;/code&gt; when installing gems so you&amp;rsquo;ll need to take care and remember that. The &lt;a href="http://rvm.beginrescueend.com/gems/"&gt;gems page&lt;/a&gt; on the rvm site has more details about this.&lt;/p&gt;

&lt;p&gt;Once both commands have run we&amp;rsquo;ll have Rails 3.0 installed and we can start trying it out.&lt;/p&gt;

&lt;h3&gt;Using Rails 3.0&lt;/h3&gt;

&lt;p&gt;First we&amp;rsquo;ll make sure that Rails 3 has been installed by running &lt;code&gt;rails -v&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rails -v
Rails 3.0.0.beta
&lt;/pre&gt;
&lt;p&gt;If you see an error when you try this then you should close your terminal window and reopen it then try the command again. Once we know we have Rails 3.0 working we can create our first application. This will be a very simple application that will store game highscores and we&amp;rsquo;ll call it &lt;code&gt;topscore&lt;/code&gt;. We create a Rails 3.0 application in the same way we always have:&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails topscore
&lt;/pre&gt;
&lt;p&gt;But when we move to the application&amp;rsquo;s directory and try to start the server we&amp;rsquo;ll notice the first difference.&lt;/p&gt;
&lt;pre class="terminal"&gt;&#184;
$ script/server
-bash: script/server: No such file or directory
&lt;/pre&gt;
&lt;p&gt;None of the commands under the &lt;code&gt;script&lt;/code&gt; directory are there any more so how do we start the server? The answer is that we run them through the &lt;code&gt;rails&lt;/code&gt; command like this:&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails server
&lt;/pre&gt;
&lt;p&gt;When we run this now though we&amp;rsquo;ll get a huge error message for our troubles, but small stumbling blocks like this are to be expected in a beta release. If we look through the error message we&amp;rsquo;ll see an error about a missing &lt;code&gt;sqlite3-ruby&lt;/code&gt; gem. As we already have that gem installed on our machine this might be a little confusing but each version of Ruby we have installed comes with it own basic set of RubyGems so any additional gems needed will have to be installed for each version. Therefore we&amp;rsquo;ll need to install the &lt;code&gt;sqlite3-ruby&lt;/code&gt;  gem for Ruby 1.9.1, again making sure not to prefix it with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
gem install sqlite3-ruby
&lt;/pre&gt;
&lt;p&gt;This time when we run &lt;code&gt;rails server&lt;/code&gt; we&amp;rsquo;ll see a lot of output and a few warnings but the server will start. If we visit &lt;a href="http://localhost:3000/"&gt;http://localhost:3000&lt;/a&gt; with a browser we&amp;rsquo;ll see the default Rails page.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/326/original/E200I01.png" width="785" height="515" alt="The welcome page for our first Rails 3.0 application."/&gt;
&lt;/div&gt;

&lt;p&gt;Now we can start building our application. We&amp;rsquo;ll start by generating the scaffolding for a &lt;code&gt;Game&lt;/code&gt; model that will have a &lt;code&gt;name&lt;/code&gt; attribute of type &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails generate scaffold game name:string
&lt;/pre&gt;
&lt;p&gt;Again you&amp;rsquo;ll see a lot of output when we run the command but the command will work. Next we&amp;rsquo;ll migrate the database.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rake db:migrate
&lt;/pre&gt;
&lt;p&gt;If we then visit the games page we&amp;rsquo;ll see the usual scaffold-generated pages you&amp;rsquo;ll no doubt have seen before in other Rails applications.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/327/original/E200I02.png" width="799" height="283" alt="The scaffold-generated new game page."/&gt;
&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s as far as we&amp;rsquo;re going to take this application. In future episodes we&amp;rsquo;ll be covering the new features of Rails 3 in depth but in the mean time it&amp;rsquo;s worth reading the &lt;a href="http://guides.rails.info/3_0_release_notes.html"&gt;Rails 3.0 Release Notes&lt;/a&gt; for an overview of what has changed. There is also an extensive collection of links about Rails 3 on &lt;a href="http://www.rubyinside.com/rails-3-0-beta-links-2966.html"&gt;Ruby Inside&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you will be working with beta software there is a chance that things won&amp;rsquo;t work quite correctly and you&amp;rsquo;ll come across bugs or problems. If you do come across an error that you know isn&amp;rsquo;t related to your code the first thing to do is to check which additional gems or plugins your application is using. There&amp;rsquo;s a good chance that one of these may be causing the problem as it may have not yet been upgraded to work with Rails 3 or Ruby 1.9. If you do track a problem to a specific gem or plugin then you should add an issue or ticket on that gem&amp;rsquo;s project page so that it can be addressed.&lt;/p&gt;

&lt;p&gt;If you know that the problem is with Rails itself then you can submit a ticket at the &lt;a href="https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets?q=all"&gt;Rails Lighthouse&lt;/a&gt;. If you do decide to submit an issue then it&amp;rsquo;s worth bearing the following tips in mind. Firstly you should search through the  existing tickets and make sure that you&amp;rsquo;re not duplicating an existing issue. When you&amp;rsquo;re writing your ticket make sure to include instructions on how to reproduce the error along with the full error messages and stack trace that you get. Finally include the exact version of Ruby and Rails that you&amp;rsquo;re running 
along with the plugins and gems you have installed so that it is easier to duplicate the problem. Submitting good tickets will help them be noticed and make it easier to fix the problem.&lt;/p&gt;

&lt;h3&gt;Give Back To Open Source&lt;/h3&gt;

&lt;p&gt;As you&amp;rsquo;ve probably noticed this is episode 200 and to mark the 200th Railscast Ryan Bates is launching a campaign called &lt;a href="http://railscasts.com/give_back"&gt;&amp;ldquo;Give Back To Open Source&amp;rdquo;&lt;/a&gt;. A lot of work goes into open source software which is then made freely available for anyone to use so it makes sense to give something back when we can. Ryan&amp;rsquo;s challenge to you is to open up your largest Rails application and look at the various plugins and gems that it uses. If you look at each gem&amp;rsquo;s project page you&amp;rsquo;ll find that many of them accept donations and even a small contribution would be greatly appreciated and help to keep that gem in development.&lt;/p&gt; 

&lt;p&gt;Alternatively you could look at the issues list for the project and fork the project and fix a bug or assist with the documentation. It up to you do decide how you contribute but you&amp;rsquo;re encouraged to do so as this will help to keep the Rails community moving forward.&lt;/p&gt;</description>
      <pubDate>Tue, 09 Feb 2010 19:39:52 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/200-rails-3-beta-and-rvm</guid>
      <link>http://asciicasts.com/episodes/200-rails-3-beta-and-rvm</link>
    </item>
    <item>
      <title>Mobile Devices</title>
      <description>  &lt;p&gt;It&amp;rsquo;s becoming more and more common to browse websites with mobile devices such as smartphones. Compared to desktop and laptop machines these have small screens and more limited abilities and given this it&amp;rsquo;s important to check your web applications on these devices to see how they work.&lt;/p&gt;

  &lt;p&gt;The best way to do this is to test your application on an actual device. Obviously &amp;ldquo;localhost&amp;rdquo; won&amp;rsquo;t work on a mobile device so you&amp;rsquo;ll need to use either the IP address of the machine your application is running on or its local domain name, assuming that your device is on the same local network. For example the machine that the application we&amp;rsquo;ll be using in this episode runs on is called noonoo so we can visit it from any other machine on the network by visiting &lt;code&gt;http://noonoo.local:3000/&lt;/code&gt;.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/316/original/E199I01.png" width="800" height="323" alt="The projects page of our application."/&gt;
  &lt;/div&gt;

  &lt;p&gt;If you don&amp;rsquo;t have access to a physical device you might be able to download a simulator for the device you want to test your web application on. If you want to test on an iPhone then a simulator is available from &lt;a href="http://developer.apple.com/iphone/program/"&gt;Apple&amp;rsquo;s Developer site&lt;/a&gt;. Likewise an emulator is provided as part of the &lt;a href="http://developer.palm.com/index.php?option=com_content&amp;amp;view=article&amp;amp;layout=page&amp;amp;id=1788"&gt;Palm Pr&amp;eacute; SDK&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;For testing on the iPhone another alternative is &lt;a href="http://sourceforge.net/projects/iphonesimulator/"&gt;iPhoney&lt;/a&gt;. This provides an almost exact emulation of an iPhone but isn&amp;rsquo;t as accurate as the simulator, although it is a much smaller download than the iPhone SDK. If you&amp;rsquo;re using it to test a site that will have different behaviour for mobile devices then you&amp;rsquo;ll need to remember to set the correct user agent from the iPhoney menu so that the correct content is shown.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/317/original/E199I02.png" width="728" height="386" alt="The site viewed in the iPhoney emulator."/&gt;
  &lt;/div&gt;
  &lt;p class="title"&gt;Our application running on iPhoney.&lt;/p&gt;

  &lt;p&gt;This application&amp;rsquo;s appearance could definitely be improved for display on a mobile device and we&amp;rsquo;re going to spend the rest of the episode doing this.&lt;/p&gt;

  &lt;p&gt;To start we&amp;rsquo;ll add a stylesheet in our application&amp;rsquo;s layout file that will only be included if the application is being viewed on a mobile device.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/views/products/_fields.html.erb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  &amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;
    &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;
  &amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
      &amp;lt;title&amp;gt;&amp;lt;%= h(yield(:title) || &amp;quot;Untitled&amp;quot;) %&amp;gt;&amp;lt;/title&amp;gt;
      &amp;lt;%= stylesheet_link_tag &amp;#x27;application&amp;#x27; %&amp;gt;
      &amp;lt;%= stylesheet_link_tag &amp;#x27;mobile&amp;#x27; if mobile_device? %&amp;gt;
      &amp;lt;%= yield(:head) %&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
    &amp;lt;!-- content omitted --&amp;gt;
    &amp;lt;/body&amp;gt;
  &amp;lt;/html&amp;gt;
  &lt;/pre&gt;
  &lt;p&gt;The new mobile stylesheet will only be included if a method called &lt;code&gt;mobile_device?&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;, and we&amp;rsquo;ll have to write this method. We could make use of the &lt;code&gt;media&lt;/code&gt; attribute that the &lt;code&gt;link&lt;/code&gt; element has to restrict the devices that would make use of the stylesheet, but mobile browsers can interpret this attribute in different ways. By using our own method to determine whether to include the stylesheet or not we can control which devices will include it by reading the user agent string sent by the browser.&lt;/p&gt;

  &lt;p&gt;Our next task is to write the &lt;code&gt;mobile_device?&lt;/code&gt; method. We&amp;rsquo;ll put this in in the application controller so that the controllers can have access to this method.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/controllers/application_controller.rb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  class ApplicationController &amp;lt; ActionController::Base
    helper :all
    protect_from_forgery

    private
    def mobile_device?
      request.user_agent =~ /Mobile|webOS/
    end
    helper_method :mobile_device?
  end
  &lt;/pre&gt;
  &lt;p&gt;Inside the method we check the request&amp;rsquo;s user agent to see if it contains either the word &amp;ldquo;Mobile&amp;rdquo;, which will match iPhone and Android devices or &amp;ldquo;webOS&amp;rdquo; which will match the Palm Pr&amp;eacute;. You can, of course, customise the regular expression to target whichever devices you want to show the mobile stylesheet. Finally we mark the method as a helper method so that we can access it from our views. If you want to be able to target a specific device there is a &lt;a href="http://www.zytrax.com/tech/web/mobile_ids.html"&gt;comprehensive list&lt;/a&gt; of mobile device agent ids available. &lt;/p&gt;

  &lt;p&gt;Now that we&amp;rsquo;ve written the helper method we&amp;rsquo;ll create the mobile stylesheet that mobile devices will use.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/public/stylesheets/mobile.css&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  body {
    background-color: #FFF;
  }

  #container {
    width: 90%;
    min-width: none;
    margin: 0 auto;
    background-color: #FFF;
    padding: 0;
    border: none;
    margin-top: 20px;
  }
  &lt;/pre&gt;
  &lt;p&gt;To see how the page looks with the mobile stylesheet we can make use of Safari&amp;rsquo;s user agent swapping feature. Under the &lt;code&gt;Develop &amp;gt; User Agent&lt;/code&gt; menu is a list of user agent strings that can be selected, including several for various versions of Mobile Safari. If we pick one of these and look at our application again we&amp;rsquo;ll see the page with the mobile stylesheet applied.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/318/original/E199I03.png" width="800" height="280" alt="The site with the mobile stylesheet applied."/&gt;
  &lt;/div&gt;

  &lt;h3&gt;Swapping Between Sites&lt;/h3&gt;

&lt;p&gt;Now that we have our &lt;code&gt;mobile_device?&lt;/code&gt; helper method we can use it to alter the behaviour of the site depending on the device that is viewing it. One thing we&amp;rsquo;ll add is a link that will allow users to swap between the full and mobile versions of the site. To do this we&amp;rsquo;ll modify our application&amp;rsquo;s layout file by adding the following code at the top of the &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  &amp;lt;p&amp;gt;
    &amp;lt;% if mobile_device? %&amp;gt;
      &amp;lt;%= link_to &amp;quot;Full Site&amp;quot;, :mobile =&amp;gt; 0 %&amp;gt;
    &amp;lt;% else %&amp;gt;
      &amp;lt;%= link_to &amp;quot;Mobile Site&amp;quot;, :mobile =&amp;gt; 1 %&amp;gt;
    &amp;lt;% end %&amp;gt;
  &amp;lt;/p&amp;gt;
  &lt;/pre&gt;
  &lt;p&gt;This code will show a link to the full site if we&amp;rsquo;re currently looking at the mobile one and vice versa. The link will redirect to the page that&amp;rsquo;s currently being viewed with a query string parameter called mobile that will determine which version of the site to show.&lt;/p&gt;

&lt;p&gt;In our application controller we can set up a &lt;code&gt;before_filter&lt;/code&gt; that will set a session variable  so that once the link has been clicked that version will continue to be seen as the user navigates through the site. The &lt;code&gt;before_filter&lt;/code&gt; will set a session variable if there is a mobile parameter in the query string. We&amp;rsquo;ll also modify our &lt;code&gt;mobile_device?&lt;/code&gt; method so that it will check to see if that session variable exists and, if it does, decide which version of the site to show depending on its value. If the session variable hasn&amp;rsquo;t been set we&amp;rsquo;ll decide based on the user string.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/controllers/application_controller.rb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  class ApplicationController &amp;lt; ActionController::Base
    helper :all
    protect_from_forgery
    before_filter :prepare_for_mobile

    private
    def mobile_device?
      if session[:mobile_param]
        session[:mobile_param] == &amp;quot;1&amp;quot;
      else
        request.user_agent =~ /Mobile|webOS/
      end
    end
    helper_method :mobile_device?

    def prepare_for_mobile
      session[:mobile_param] = params[:mobile] if params[:mobile]
    end
  end
  &lt;/pre&gt;
  &lt;p&gt;If we reload the page now there&amp;rsquo;ll be a link to the full version of the site and if we click that link we&amp;rsquo;ll see the full version even though we&amp;rsquo;re viewing the page with a user agent string that contains the word &amp;ldquo;mobile&amp;rdquo;.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/319/original/E199I04.png" width="800" height="353" alt="The link to the mobile site is now visible."/&gt;
  &lt;/div&gt;

  &lt;p&gt;This preference will persist so that clicking any of the links above will keep us on the full version of the application.&lt;/p&gt;

  &lt;h3&gt;Separate Views For Mobile Devices&lt;/h3&gt;

  &lt;p&gt;What we&amp;rsquo;ve done so far will work for the cases where we want to fine-tune the application for mobile devices, but what if we have grander plans and want to change the application so that it looks and behaves more like a native application when viewed on a mobile device? To do this we&amp;rsquo;ll need to change pretty much every view in our application. How would we go about doing that?&lt;/p&gt;

  &lt;p&gt;The trick to doing this is to create a new MIME type in our application and Rails provides a file for doing just that at &lt;code&gt;/config/initializers/mime_types.rb&lt;/code&gt;. The file contains a commented-out example for providing a new &lt;code&gt;iphone&lt;/code&gt; type which we can modify to create a new &lt;code&gt;mobile&lt;/code&gt; one. This gives us an alternative HTML format for mobile devices.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/config/initializers/mime_types.rb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  # Be sure to restart your server when you modify this file.

  # Add new mime types for use in respond_to blocks:
  # Mime::Type.register &amp;quot;text/richtext&amp;quot;, :rtf
  # Mime::Type.register_alias &amp;quot;text/html&amp;quot;, :iphone
  Mime::Type.register_alias &amp;quot;text/html&amp;quot;, :mobile
  &lt;/pre&gt;
  &lt;p&gt;We still need to set that MIME type, however and to do so we need to go back to the &lt;code&gt;before_filter&lt;/code&gt; in our application controller and set the format to &lt;code&gt;:mobile&lt;/code&gt; if the mobile version of the site is being viewed.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/controllers/application_controller.rb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  def prepare_for_mobile
    session[:mobile_param] = params[:mobile] if params[:mobile]
    format :mobile if mobile_device?
  end
  &lt;/pre&gt;
  &lt;p&gt;Now that the MIME type is set we can use it in our controllers&amp;rsquo; actions to change the behaviour of each action depending on that type by using &lt;code&gt;respond_to&lt;/code&gt;, as we&amp;rsquo;ll demonstrate in the &lt;code&gt;index&lt;/code&gt; action of the projects controller.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/controllers/projects_controller.rb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  def index
    @projects = Project.all
    respond_to do |format|
      format.html
      format.mobile
    end
  end
  &lt;/pre&gt;
  &lt;p&gt;The &lt;code&gt;respond_to&lt;/code&gt; block isn&amp;rsquo;t necessary, however, if we&amp;rsquo;re just providing an alternative view based on the format. In that case we just need to provide a new template with the name of the format in it where you would normally have html. For the index view above we&amp;rsquo;ll  create a file called &lt;code&gt;/app/views/projects/index.mobile.erb&lt;/code&gt; and to start with we&amp;rsquo;ll just put some text in the file.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/views/projects/index.mobile.erb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  This is a mobile version!
  &lt;/pre&gt;
  &lt;p&gt;If we visit the mobile version of that page now we&amp;rsquo;ll see the mobile view rendered.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/320/original/E199I05.png" width="740" height="280" alt="The mobile view template is now rendered."/&gt;
  &lt;/div&gt;

  &lt;p&gt;Now that we have this in place we can create a UI that will fell much more like a native mobile application. There are a couple of libraries that we can use to make this easier: &lt;a href="http://code.google.com/p/iui/"&gt;iui&lt;/a&gt; and &lt;a href="http://www.jqtouch.com"&gt;jQTouch&lt;/a&gt; and we&amp;rsquo;ll be using jQTouch here. jQTouch makes it a lot easier to create a web application that looks and behaves like a native iPhone app.&lt;/p&gt;

  &lt;p&gt;After we&amp;rsquo;ve downloaded and unzipped jQTouch it will have a folder structure like this:&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/321/original/E199I06.png" width="808" height="393" alt="The directory structure for jQTouch."/&gt;
  &lt;/div&gt;

  &lt;p&gt;To make jQTouch easier to work with we&amp;rsquo;re going to move the extensions and themes folders into the &lt;code&gt;jqtouch&lt;/code&gt; folder and then drag that folder into the our application&amp;rsquo;s &lt;code&gt;public&lt;/code&gt; folder.&lt;/p&gt;

  &lt;p&gt;Next we&amp;rsquo;ll create a new layout file for the mobile version of our application.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/views/layouts/application.mobile.erb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  &amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;
    &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;
  &amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
      &amp;lt;title&amp;gt;&amp;lt;%= h(yield(:title) || &amp;quot;Untitled&amp;quot;) %&amp;gt;&amp;lt;/title&amp;gt;
      &amp;lt;%= stylesheet_link_tag &amp;quot;/jqtouch/jqtouch.min.css&amp;quot;, &amp;quot;/jqtouch/themes/apple/theme.min.css&amp;quot; %&amp;gt;
      &amp;lt;%= javascript_include_tag &amp;quot;/jqtouch/jquery.1.3.2.min.js&amp;quot;, &amp;quot;/jqtouch/jqtouch.min.js&amp;quot;, &amp;quot;mobile&amp;quot; %&amp;gt;
      &amp;lt;%= yield(:head) %&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
      &amp;lt;div class=&amp;quot;current&amp;quot;&amp;gt;
        &amp;lt;%- if show_title? -%&amp;gt;
        &amp;lt;div class=&amp;quot;toolbar&amp;quot;&amp;gt;
          &amp;lt;%= link_to &amp;quot;Back&amp;quot;, nil, :class =&amp;gt; &amp;quot;back&amp;quot; unless current_page? root_path %&amp;gt;
          &amp;lt;h1&amp;gt;&amp;lt;%=h yield(:title) %&amp;gt;&amp;lt;/h1&amp;gt;
          &amp;lt;%= yield(:toolbar) %&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;%- end -%&amp;gt;

        &amp;lt;% unless flash.empty? %&amp;gt;
          &amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;
          &amp;lt;%- flash.each do |name, msg| -%&amp;gt;
            &amp;lt;%= content_tag :div, msg, :id =&amp;gt; &amp;quot;flash_#{name}&amp;quot; %&amp;gt;
          &amp;lt;%- end -%&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;% end %&amp;gt;

        &amp;lt;%= yield %&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
  &amp;lt;/html&amp;gt;
  &lt;/pre&gt;
  &lt;p&gt;In this layout file we include a couple of the CSS files that jQTouch provides along with references to &lt;code&gt;jQuery&lt;/code&gt; and the &lt;code&gt;jQTouch&lt;/code&gt; JavaScript. There is also a reference to a &lt;code&gt;mobile.js&lt;/code&gt; file that we&amp;rsquo;ll create. In the layout the content of the page is wrapped in a &lt;code&gt;div&lt;/code&gt; with a class of &lt;code&gt;current&lt;/code&gt;. If the page should show a title then we&amp;rsquo;ll show it wrapped in another &lt;code&gt;div&lt;/code&gt; with  the class toolbar. Likewise if there is any flash text to show it will be displayed in another &lt;code&gt;div&lt;/code&gt;, this time with an &lt;code&gt;info&lt;/code&gt; class. Below that we &lt;code&gt;yield&lt;/code&gt; to whatever is in the current template.&lt;/p&gt;

  &lt;p&gt;Next we&amp;rsquo;ll need to create the new &lt;code&gt;mobile.js&lt;/code&gt; file. All we need to put in it is a call to the jQTouch initializer.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/public/javascripts/mobile.js&lt;/p&gt;
  &lt;pre class="javascript"&gt;
  $.jQTouch({});
  &lt;/pre&gt;
  &lt;p&gt;The initialiser function takes a &lt;a href="http://code.google.com/p/jqtouch/wiki/InitOptions"&gt;hash of options&lt;/a&gt; but we won&amp;rsquo;t be setting any of them here. When we reload the mobile projects page again we&amp;rsquo;ll see the jQTouch styles applied, but the page will look fairly ugly as we don&amp;rsquo;t have any content in the page&amp;rsquo;s template.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/322/original/E199I07.png" width="814" height="293" alt="The jQTouch CSS is now applied."/&gt;
  &lt;/div&gt;

  &lt;p&gt;If we go back to the page&amp;rsquo;s mobile view code we can replace the placeholder code with some code that will list all of the projects and a count of the number of tasks that each one has and a link to create a new project.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/views/projects/index.mobile.erb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  &amp;lt;% title &amp;quot;Projects&amp;quot; %&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;% for project in @projects %&amp;gt;
    &amp;lt;li class=&amp;quot;arrow&amp;quot;&amp;gt;
      &amp;lt;%= link_to h(project.name), project %&amp;gt;
      &amp;lt;small class=&amp;quot;counter&amp;quot;&amp;gt;&amp;lt;%= project.tasks.size %&amp;gt;&amp;lt;/small&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;% end %&amp;gt;
  &amp;lt;/ul&amp;gt;
  &amp;lt;ul&amp;gt;&amp;lt;li class=&amp;quot;arrow&amp;quot;&amp;gt;&amp;lt;%= link_to &amp;quot;New Project&amp;quot;, new_project_path %&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;
  &lt;/pre&gt;
  &lt;p&gt;Reloading the page again we&amp;rsquo;ll see a nice interface that looks a lot like a native mobile application.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/323/original/E199I08.png" width="784" height="350" alt="The mobile version of the home page now looks like a native application."/&gt;
  &lt;/div&gt;

  &lt;p&gt;Obviously the interface will be rather narrower when viewed on an actual iPhone, but it works just as well on a desktop browser.&lt;/p&gt; 

  &lt;p&gt;Every view file in our application will need a mobile version too. There&amp;rsquo;s too much code to list here, but you can &lt;a href="http://github.com/ryanb/railscasts-episodes/tree/master/episode-199/"&gt;download the files&lt;/a&gt; from Ryan Bates&amp;rsquo; Github page. Once we&amp;rsquo;ve done that we&amp;rsquo;ll have a fully functional mobile application that looks like a native application.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/324/original/E199I09.png" width="783" height="285" alt="The new project page on the mobile site."/&gt;
  &lt;/div&gt;

  &lt;p&gt;While the mobile version of our site now looks a lot better we&amp;rsquo;ve lost the ability to swap to the full version of the site. We&amp;rsquo;ll add a button on the righthand side of the top toolbar to reenable this.&lt;/p&gt;

  &lt;p&gt;The toolbar is defined in the mobile layout file and adding new controls to it is easy as the jQTouch elements are defined with HTML tags. We can add a new button by creating a new link within the toolbar div and giving it a &lt;code&gt;class&lt;/code&gt; of &lt;code&gt;button&lt;/code&gt;.&lt;/p&gt;

  &lt;p class="codeFilePath"&gt;/app/views/layouts/application.mobile.erb&lt;/p&gt;
  &lt;pre class="ruby"&gt;
  &amp;lt;div class=&amp;quot;toolbar&amp;quot;&amp;gt;
    &amp;lt;%= link_to &amp;quot;Back&amp;quot;, nil, :class =&amp;gt; &amp;quot;back&amp;quot; unless current_page? root_path %&amp;gt;
    &amp;lt;h1&amp;gt;&amp;lt;%=h yield(:title) %&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;%= link_to &amp;quot;Full Site&amp;quot;, root_url(:mobile =&amp;gt; 0), :class =&amp;gt; &amp;quot;button&amp;quot;, :rel =&amp;gt; &amp;quot;external&amp;quot; %&amp;gt;
     &amp;lt;%= yield(:toolbar) %&amp;gt;
  &amp;lt;/div&amp;gt;
  &lt;/pre&gt;
  &lt;p&gt;We also need to provide a &lt;code&gt;rel&lt;/code&gt; attribute with a value of &lt;code&gt;external&lt;/code&gt; so that jQTouch will treat the link as a link to another site. If we don&amp;rsquo;t do this it will make an AJAX request which isn&amp;rsquo;t what we want.&lt;/p&gt; 

  &lt;p&gt;When we reload the page one last time we&amp;rsquo;ll have a button on each page now that will take us back to the full version.&lt;/p&gt;

  &lt;div class="imageWrapper"&gt;
    &lt;img src="/system/photos/325/original/E199I10.png" width="783" height="285" alt="The mobile site now has a link to the full version."/&gt;
  &lt;/div&gt;</description>
      <pubDate>Thu, 04 Feb 2010 21:58:39 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/199-mobile-devices</guid>
      <link>http://asciicasts.com/episodes/199-mobile-devices</link>
    </item>
    <item>
      <title>Edit Multiple Individually</title>
      <description>&lt;p&gt;In episode 165 [&lt;a href="http://railscasts.com/episodes/165-edit-multiple"&gt;watch&lt;/a&gt;, &lt;a href="http://asciicasts.com/episodes/165-edit-multiple"&gt;read&lt;/a&gt;], we created an application that could edit multiple records simultaneously. Each record on the index page had a checkbox against it so that we could choose which items we wanted to edit and then update the fields for those items.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/307/original/E198I01.png" width="812" height="362" alt="The products list from our previous application."/&gt;
&lt;/div&gt;

&lt;p&gt;If we select the three products above then click &amp;ldquo;edit checked&amp;rdquo; we can then update the category, name or price for those products, for example putting them all into the &amp;ldquo;groceries&amp;rdquo; category.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/308/original/E198I02.png" width="814" height="522" alt="Updating the category for a number of products."/&gt;
&lt;/div&gt;

&lt;p&gt;The obvious restriction is that any changes we make are applied to all of the checked products, so in this episode we&amp;rsquo;ll write a similar application that will show a separate set of fields for each checked product so that we can update multiple products on a single form, each with their own set of values.&lt;/p&gt; 

&lt;h3&gt;Adding The Checkboxes&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/309/original/E198I03.png" width="809" height="319" alt="The scaffold-generated table for products."/&gt;
&lt;/div&gt;

&lt;p&gt;We&amp;rsquo;ll start with a basic scaffolding for listing products. The scaffolding code gives us the ability to edit products individually, but of course that&amp;rsquo;s not what we want to do. As we did last time we&amp;rsquo;re going to add a checkbox against each item so that we can choose the items we want to edit. The first change we&amp;rsquo;re going to make therefore will be to the products &lt;code&gt;index&lt;/code&gt; view.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;
&amp;lt;% form_tag edit_individual_products_path do %&amp;gt;
  &amp;lt;table&amp;gt;
    &amp;lt;thead&amp;gt;
      &amp;lt;tr&amp;gt;
        &amp;lt;th&amp;gt;&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;Category&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;Price&amp;lt;/th&amp;gt;
      &amp;lt;/tr&amp;gt;
    &amp;lt;/thead&amp;gt;
    &amp;lt;tbody&amp;gt;
      &amp;lt;% for product in @products %&amp;gt;
      &amp;lt;tr&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= check_box_tag &amp;quot;product_ids[]&amp;quot;, product.id %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= product.name %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= product.category.name %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= number_to_currency product.price, :unit =&amp;gt; &amp;quot;&amp;amp;pound;&amp;quot; %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;quot;Edit&amp;quot;, edit_product_path(product) %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;quot;Destroy&amp;quot;, product_path(product), :confirm =&amp;gt; &amp;quot;Are you sure?&amp;quot;, :method =&amp;gt; :delete %&amp;gt;&amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
      &amp;lt;% end %&amp;gt;
    &amp;lt;/tbody&amp;gt;
  &amp;lt;/table&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= submit_tag &amp;quot;Edit Checked&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%= link_to &amp;quot;New Product&amp;quot;, new_product_path %&amp;gt;&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To add the checkboxes we have made a number of changes to the scaffolded code. Firstly we&amp;rsquo;ve wrapped the table in a form using &lt;code&gt;form_tag&lt;/code&gt;.&lt;/p&gt; 
&lt;pre class="ruby"&gt;
&amp;lt;% form_tag edit_individual_products_path do %&amp;gt;
  &amp;lt;!-- table --&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The form will be submitted to a new action in the products controller called &lt;code&gt;edit_individual&lt;/code&gt; that we&amp;rsquo;ll write shortly. In the table itself we&amp;rsquo;ll add a new &lt;code&gt;th&lt;/code&gt; element in the header then, in the table&amp;rsquo;s body, a new cell to hold the checkbox, which we&amp;rsquo;ll declare with&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;%= check_box_tag &amp;quot;product_ids[]&amp;quot;, product.id %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The name we pass to &lt;code&gt;check_box_tag&lt;/code&gt; is &lt;code&gt;product_ids[]&lt;/code&gt;, the empty square brackets mean that we can pass multiple product &lt;code&gt;id&lt;/code&gt;s as an array for all of the checked boxes. We also pass the product&amp;rsquo;s &lt;code&gt;id&lt;/code&gt; as a value for each checkbox.&lt;/p&gt;

&lt;p&gt;Finally we add a submit tag so that we can submit the form.&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;%= submit_tag &amp;quot;Edit Checked&amp;quot; %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The form submits to new action called &lt;code&gt;edit_individual&lt;/code&gt; so the next thing we&amp;rsquo;ll need to do is write that action in the products controller, along with another one called &lt;code&gt;update_individual&lt;/code&gt; that the &lt;code&gt;edit_individual&lt;/code&gt; action will submit to when we update the selected products.&lt;/p&gt;
&lt;p class="codeFilePath"&gt;/app/controllers/products_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
def edit_individual

end

def update_individual

end
&lt;/pre&gt;
&lt;p&gt;As we&amp;rsquo;re adding actions to a RESTful resource we&amp;rsquo;ll also need to make a change to the routes file.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/config/routes.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
ActionController::Routing::Routes.draw do |map|
  map.resources :products, :collection =&amp;gt; { :edit_individual =&amp;gt; :post, :update_individual =&amp;gt; :put }
  map.resources :categories
  map.root :products
end
&lt;/pre&gt;
&lt;p&gt;We modify the products resource in &lt;code&gt;routes.rb&lt;/code&gt;, adding a &lt;code&gt;:collection&lt;/code&gt; argument with the two new actions. &lt;code&gt;:edit_individual&lt;/code&gt; will be a POST request as we&amp;rsquo;re submitting to it through a form. We&amp;rsquo;re just fetching information so a GET request would be ideal but as we&amp;rsquo;re submitting multiple ids a POST is necessary. We&amp;rsquo;ll be updating records in &lt;code&gt;:update_individual&lt;/code&gt; so this will be a PUT request.&lt;/p&gt;

&lt;p&gt;If we reload the index page now we&amp;rsquo;ll see checkboxes against each product and a button that we can click to edit those products.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/310/original/E198I04.png" width="809" height="361" alt="The products index with checkboxes and an edit button added."/&gt;
&lt;/div&gt;

&lt;p&gt;We&amp;rsquo;ve not written the &lt;code&gt;edit_individual&lt;/code&gt; template yet so we&amp;rsquo;ll see an error if we were to submit the form now. Before we create the template we&amp;rsquo;ll modify the &lt;code&gt;edit_individual&lt;/code&gt; action so that it fetches all of the products with &lt;code&gt;id&lt;/code&gt;s that match the array of &lt;code&gt;product_ids&lt;/code&gt; from the checked checkboxes that are passed in.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/products_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
def edit_individual
  @products = Product.find(params[:product_ids])
end
&lt;/pre&gt;
&lt;p&gt;Now on to the &lt;code&gt;edit_individual&lt;/code&gt; view code. We give the page a title and then create a form, but  should we use &lt;code&gt;form_for&lt;/code&gt; or &lt;code&gt;form_tag&lt;/code&gt; here? Well, &lt;code&gt;form_for&lt;/code&gt; is meant to be used when editing a single model, but here we&amp;rsquo;re editing a number of models at once so we&amp;rsquo;ll use &lt;code&gt;form_tag&lt;/code&gt;. We&amp;rsquo;ll pass it the URL to the &lt;code&gt;update&lt;/code&gt; action and specify the method as PUT.&lt;/p&gt;

&lt;p&gt;Inside the form we&amp;rsquo;ll loop through the list of products and use &lt;code&gt;fields_for&lt;/code&gt; to generate the fields for each product. We do this by passing &lt;code&gt;products[]&lt;/code&gt; and the product to &lt;code&gt;fields_for&lt;/code&gt;. This will insert the product&amp;rsquo;s &lt;code&gt;id&lt;/code&gt; into the empty square brackets so that each product is passed as a separate parameter. We&amp;rsquo;ll need to put the form fields themselves in next, but for now we&amp;rsquo;ll just print each product&amp;rsquo;s name. Finally we add a &lt;code&gt;submit_tag&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/edit_individual.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% title &amp;quot;Edit Products&amp;quot; %&amp;gt;

&amp;lt;% form_tag update_individual_products_path :method =&amp;gt; :put do %&amp;gt;
  &amp;lt;% for product in @products %&amp;gt;
    &amp;lt;% fields_for &amp;quot;products[]&amp;quot;, product do |f| %&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;%= h product.name %&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;% end %&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= submit_tag &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;So, if we check the checkboxes for our three products and click &amp;ldquo;Edit Checked&amp;rdquo; we&amp;rsquo;ll be taken to the new &lt;code&gt;edit_individual&lt;/code&gt; page and we&amp;rsquo;ll see the three products listed.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/311/original/E198I05.png" width="810" height="365" alt="The new edit_individual action before we add the form fields."/&gt;
&lt;/div&gt;

&lt;p&gt;Along with the product&amp;rsquo;s name we want to show form fields for each product&amp;rsquo;s attributes. As these fields are also shown in the product&amp;rsquo;s &lt;code&gt;new&lt;/code&gt; and &lt;code&gt;edit&lt;/code&gt; actions the form itself is usually separated out into a partial. This partial contains a &lt;code&gt;form_for&lt;/code&gt; tag which wraps the form elements for a product. We want to reuse the fields without the surrounding &lt;code&gt;form_for&lt;/code&gt; so we&amp;rsquo;ll extract the fields into another partial that we can use both in the form and in the multiple edit page.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll put the form fields into a new partial called &lt;code&gt;_fields.html.erb&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;%= f.error_messages %&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :price %&amp;gt;
  &amp;lt;%= f.text_field :price %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :category_id %&amp;gt;
  &amp;lt;%= f.collection_select :category_id, Category.all, :id, :name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.check_box :discontinued %&amp;gt;
  &amp;lt;%= f.label :discontinued %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We can then call this new partial from the &lt;code&gt;_form&lt;/code&gt; partial, passing in the &lt;code&gt;f&lt;/code&gt; variable.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/_form.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @product do |f| %&amp;gt;
&amp;lt;%= render :partial =&amp;gt; &amp;#x27;fields&amp;#x27;, :f =&amp;gt; f %&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%= form.submit &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Back in the &lt;code&gt;edit_individual&lt;/code&gt; view code we can call this partial so that the fields for each product will be rendered.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/edit_individual.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% content_for :title do %&amp;gt;
  Edit Individual
&amp;lt;% end %&amp;gt;

&amp;lt;% form_tag update_individual_products_path, :method =&amp;gt; :put do %&amp;gt;
  &amp;lt;% for product in @products %&amp;gt;
    &amp;lt;% fields_for &amp;quot;products[]&amp;quot;, product do |f| %&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;%= h product.name %&amp;gt;&amp;lt;/h2&amp;gt;
      &amp;lt;%= render &amp;quot;fields&amp;quot;, :f =&amp;gt; f %&amp;gt;
    &amp;lt;% end %&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= submit_tag &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;When we reload the page now we&amp;rsquo;ll see the form fields for each of the selected products with their values filled in.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/312/original/E198I06.png" width="823" height="620" alt="We now have form fields for each product."/&gt;
&lt;/div&gt;

&lt;p&gt;If we look at the appropriate part of the page&amp;rsquo;s source code we can see that the form fields have interesting names. Each name begins with &lt;code&gt;products&lt;/code&gt; then has the product&amp;rsquo;s &lt;code&gt;id&lt;/code&gt; and its field name in square brackets. This means that the products&amp;rsquo; values will be sent as a hash.&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;lt;p&amp;gt;
  &amp;lt;label for=&amp;quot;products_3_name&amp;quot;&amp;gt;Name&amp;lt;/label&amp;gt;
  &amp;lt;input id=&amp;quot;products_3_name&amp;quot; name=&amp;quot;products[3][name]&amp;quot; size=&amp;quot;30&amp;quot; type=&amp;quot;text&amp;quot; value=&amp;quot;Stereolab T-Shirt&amp;quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;label for=&amp;quot;products_3_price&amp;quot;&amp;gt;Price&amp;lt;/label&amp;gt;
  &amp;lt;input id=&amp;quot;products_3_price&amp;quot; name=&amp;quot;products[3][price]&amp;quot; size=&amp;quot;30&amp;quot; type=&amp;quot;text&amp;quot; value=&amp;quot;12.49&amp;quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;

&lt;p&gt;We can use that &lt;code&gt;products&lt;/code&gt; parameter in the &lt;code&gt;update_individual&lt;/code&gt; action to update all of the products when the form is submitted. We need to update multiple products simultaneously and there&amp;rsquo;s an ActiveRecord method called update that will do just that for us. update takes two arguments: the first one is either a single &lt;code&gt;id&lt;/code&gt; or an array of &lt;code&gt;id&lt;/code&gt;s and the second is a hash of values. To update our products we can pass in the &lt;code&gt;keys&lt;/code&gt; and &lt;code&gt;values&lt;/code&gt; from our products parameter. After updating the products we&amp;rsquo;ll create a flash message and then redirect to the products index page.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/products_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
def update_individual
  Product.update(params[:products].keys, params[:products].values)
  flash[:notice] = &amp;quot;Products updated&amp;quot;
  redirect_to products_url
end
&lt;/pre&gt;
&lt;p&gt;All of our products are currently in the &amp;ldquo;Groceries&amp;rdquo; category which is clearly wrong. We&amp;rsquo;ll change the categories of the t-shirt and DVD player and reduce their prices a little and submit the form. When we do we&amp;rsquo;ll be directed to the index page where we can see the updated products.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/313/original/E198I07.png" width="811" height="383" alt="The index page after updating two products."/&gt;
&lt;/div&gt;

&lt;p&gt;This means that our form works as we want it to and we can update a number of products at once.&lt;/p&gt;

&lt;h3&gt;Validations&lt;/h3&gt;

&lt;p&gt;If someone tries to enter invalid values on the new form we want to display any errors in a useful way. The &lt;code&gt;Product&lt;/code&gt; model currently doesn&amp;rsquo;t have any validations so we&amp;rsquo;ll add one to ensure that the price is numeric.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/product.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Product &amp;lt; ActiveRecord::Base
  belongs_to :category
  validates_numericality_of :price  
end
&lt;/pre&gt;
&lt;p&gt;In the products controller we now need to handle validation in the &lt;code&gt;update_individual&lt;/code&gt; action. The &lt;code&gt;update&lt;/code&gt; method will ignore validation errors and will move on to the next record if it comes across an invalid one. All is not lost, however, as &lt;code&gt;update&lt;/code&gt; will return an array of all of the products that it tried to update and we can use that to determine which products were invalid.&lt;/p&gt;

&lt;p&gt;One way to get the invalid products would be to use the &lt;code&gt;reject&lt;/code&gt; method on the array and, in &lt;code&gt;reject&lt;/code&gt;&amp;rsquo;s block, call &lt;code&gt;valid?&lt;/code&gt; on each product to filter out the valid ones.&lt;/p&gt;
&lt;pre class="ruby"&gt;
Product.update(params[:products].keys, params[:products].values).reject { |p| p.valid? }
&lt;/pre&gt;
&lt;p&gt;The problem with this approach is that it will run the validation for each product again. A more efficient way to do this would be to reject the products with an empty &lt;code&gt;errors&lt;/code&gt; array. We&amp;rsquo;ll assign this array of invalid products to a variable and check to see if it&amp;rsquo;s empty. If it is we&amp;rsquo;ll redirect to the index page as before, otherwise we&amp;rsquo;ll re-render the &lt;code&gt;edit_individual&lt;/code&gt; form to show the errors for those invalid products.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/products_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
def update_individual
  @products = Product.update(params[:products].keys, params[:products].values).reject { |p| p.errors.empty? }
  if @products.empty? 
    flash[:notice] = &amp;quot;Products updated&amp;quot;
    redirect_to products_url
  else
    render :action =&amp;gt; &amp;#x27;edit_individual&amp;#x27;
  end
end
&lt;/pre&gt;
&lt;p&gt;If we try to edit the t-shirt and DVD player again but set an invalid value for the DVD player&amp;rsquo;s price we&amp;rsquo;ll now be returned to the edit page and shown the form again but with just the DVD player on it this time and with the validation error shown.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/314/original/E198I08.png" width="808" height="553" alt="The error message shown for an invalid product."/&gt;
&lt;/div&gt;

&lt;p&gt;The title of the error message panel is currently showing the name as &amp;ldquo;products[]&amp;rdquo;, but this is easy to fix. The error messages are generated in the fields partial using the &lt;code&gt;error_messages&lt;/code&gt; method. This takes an &lt;code&gt;:object_name&lt;/code&gt; parameter that we can use to set the name that will be displayed.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;%= f.error_messages :object_name =&amp;gt; &amp;quot;product&amp;quot; %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With that done the error message will now say &amp;ldquo;product&amp;rdquo; instead of &amp;ldquo;products[]&amp;rdquo;.&lt;/p&gt;

&lt;h3&gt;One More Thing&lt;/h3&gt;

&lt;p&gt;The functionality we were after is now pretty much complete, but to finish off this episode we&amp;rsquo;ll add one more thing to make the application more useful. If we want to change a single attribute on a number of products, for example to update the price, the edit form will become cumbersome. What we&amp;rsquo;re going to do is allow the users to select a single attribute from a list so that they can then update one attribute on a number of products without having to navigate through a long form.&lt;/p&gt;

&lt;p&gt;To do this we&amp;rsquo;ll add a pop-up menu next to the &amp;ldquo;edit checked&amp;rdquo; button on the products index page that will allow us to choose which field to edit. We can do that by adding the following line immediately before the &lt;code&gt;submit_tag&lt;/code&gt; in the products index view.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
  &amp;lt;p&amp;gt;&amp;lt;%= select_tag :field, options_for_select([[&amp;quot;All Fields&amp;quot;, &amp;quot;&amp;quot;], [&amp;quot;Name&amp;quot;, &amp;quot;name&amp;quot;], [&amp;quot;Price&amp;quot;, &amp;quot;price&amp;quot;], [&amp;quot;Category&amp;quot;, &amp;quot;category_id&amp;quot;], [&amp;quot;Discontinued&amp;quot;, &amp;quot;discontinued&amp;quot;]])%&amp;gt;&amp;lt;/p&amp;gt;
&lt;/pre&gt;  
&lt;p&gt;Now we&amp;rsquo;ll be able to choose to edit all of the fields or just a single field for each selected product. To restrict the fields that are shown we&amp;rsquo;ll have to update the fields partial so that only the selected field is shown.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;%= f.error_messages, :object_name =&amp;gt; &amp;quot;product&amp;quot; %&amp;gt;
&amp;lt;% if params[:field].blank? || params[:field] == &amp;quot;name&amp;quot; %&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&amp;lt;% if params[:field].blank? || params[:field] == &amp;quot;price&amp;quot; %&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :price %&amp;gt;
  &amp;lt;%= f.text_field :price %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&amp;lt;% if params[:field].blank? || params[:field] == &amp;quot;category_id&amp;quot; %&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :category_id %&amp;gt;
  &amp;lt;%= f.collection_select :category_id, Category.all, :id, :name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&amp;lt;% if params[:field].blank? || params[:field] == &amp;quot;discontinued&amp;quot; %&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.check_box :discontinued %&amp;gt;
  &amp;lt;%= f.label :discontinued %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;What we&amp;rsquo;ve done above is alter the partial so that it reads the &lt;code&gt;:field&lt;/code&gt; attribute from the new pop-up menu on the index form and only shows each field if the attribute is blank (i.e. if the user has selected &amp;ldquo;All Fields&amp;rdquo;) or matches the name of the field. This isn&amp;rsquo;t the tidiest code there is and could be cleaned up by making use of Formtastic but it will work for us for now.&lt;/p&gt;

&lt;p&gt;If we select two of the products from the index page now and choose &amp;ldquo;price&amp;rdquo; from the pop-up menu then the edit form will just display the price fields for those two products.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/315/original/E198I09.png" width="812" height="397" alt="Editing just one field for multiple products."/&gt;
&lt;/div&gt;

&lt;p&gt;And that&amp;rsquo;s it for this episode. Editing multiple records in a single form is fairly straightforward if you make the right use of &lt;code&gt;fields_for&lt;/code&gt; and this is a useful technique that can be applied in a number of situations.&lt;/p&gt;</description>
      <pubDate>Thu, 28 Jan 2010 20:41:25 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/198-edit-multiple-individually</guid>
      <link>http://asciicasts.com/episodes/198-edit-multiple-individually</link>
    </item>
    <item>
      <title>Nested Model Form Part 2</title>
      <description>&lt;p&gt;In the previous episode we showed you how to create a form that could handle multiple nested models. In the application we&amp;rsquo;ve created for this we have a &lt;code&gt;Survey&lt;/code&gt; model each &lt;code&gt;Survey&lt;/code&gt; having many &lt;code&gt;Questions&lt;/code&gt; and each &lt;code&gt;Question&lt;/code&gt; many &lt;code&gt;Answers&lt;/code&gt;.&lt;/p&gt; 

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/300/original/E197I01.png" width="816" height="490" alt="The edit page for a survey."/&gt;
&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;Survey&lt;/code&gt; and &lt;code&gt;Question&lt;/code&gt; models we&amp;rsquo;ve used &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; to allow us to create, edit and destroy nested records through a single model.&lt;/p&gt;

&lt;p&gt;As our application currently stands if we want to remove a question or an answer we have to use a checkbox. Also we have no way of adding new questions or answers through the form. In this episode we&amp;rsquo;ll fix these problems by using JavaScript to alter the form so that we can use links to create and destroy models dynamically.&lt;/p&gt;

&lt;p&gt;The JavaScript we&amp;rsquo;ll write involves some DOM manipulation so we&amp;rsquo;ll use the &lt;a href="http://www.prototypejs.org"&gt;Prototype library&lt;/a&gt; to make this easier. To add the Prototype code to our application we&amp;rsquo;ll add the following line to the &amp;lt;head&amp;gt; section of our application&amp;rsquo;s layout file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;%= javascript_include_tag :defaults, :cache =&amp;gt; true %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If you prefer using jQuery then you can do so and we&amp;rsquo;ll show the equivalent jQuery code at the end of the episode.&lt;/p&gt; 

&lt;h3&gt;Adding Links to Remove Answers&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll tackle the easiest part first: replacing the checkboxes we use to remove questions and answers with links. Let&amp;rsquo;s look at the answers first.&lt;/p&gt;

&lt;p&gt;The code that renders each answer is held in a partial called &lt;code&gt;answer_fields&lt;/code&gt; and looks like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/surveys/_answer_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :content, &amp;quot;Answer&amp;quot; %&amp;gt;
  &amp;lt;%= f.text_field :content %&amp;gt;
  &amp;lt;%= f.check_box :_destroy %&amp;gt;
  &amp;lt;%= f.label :_destroy, &amp;quot;Remove&amp;quot; %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;In the code above is the &lt;code&gt;_destroy&lt;/code&gt; checkbox that we check when we want an answer to be destroyed. We&amp;rsquo;re going to replace it with a hidden field whose value will be set when the &amp;ldquo;remove&amp;rdquo; link is clicked. This way we can still mark an answer for deletion.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll replace the label in the code above with a link and make use of Rails&amp;rsquo; &lt;code&gt;link_to_function&lt;/code&gt; to create a link that fires a JavaScript function when clicked. With the hidden field and the link the partial code will now look like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/surveys/_answer_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;p class=&amp;quot;fields&amp;quot;&amp;gt;
  &amp;lt;%= f.label :content, &amp;quot;Answer&amp;quot; %&amp;gt;
  &amp;lt;%= f.text_field :content %&amp;gt;
  &amp;lt;%= f.hidden_field :_destroy %&amp;gt;
  &amp;lt;%= link_to_function &amp;quot;remove&amp;quot;, &amp;quot;remove_fields(this)&amp;quot; %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;When the &amp;ldquo;remove&amp;rdquo; link next to an answer is clicked it will fire a JavaScript function called &lt;code&gt;remove_fields&lt;/code&gt;, passing in the link as an argument so that we can use it as a reference element to find the other elements related to the answer. There&amp;rsquo;s no direct way get at all those fields so we&amp;rsquo;ve added a class name to the enclosing paragraph element so that we can find them more easily.&lt;/p&gt;

&lt;p&gt;Next we&amp;rsquo;ll need to write that &lt;code&gt;remove_fields&lt;/code&gt; function. We&amp;rsquo;ll do this in the &lt;code&gt;application.js&lt;/code&gt; file as this is one of the files that is automatically included on our pages because we&amp;rsquo;ve included the JavaScript &lt;code&gt;:defaults&lt;/code&gt;.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/public/javascripts/application.js&lt;/p&gt;
&lt;pre class="javascript"&gt;
function remove_fields(link) {
	$(link).previous(&amp;quot;input[type=hidden]&amp;quot;).value = &amp;quot;1&amp;quot;;
	$(link).up(&amp;quot;.fields&amp;quot;).hide();
}
&lt;/pre&gt;

&lt;p&gt;This function performs two actions. First it uses Prototype&amp;rsquo;s &lt;a href="http://api.prototypejs.org/dom/element.html#previous-class_method"&gt;&lt;code&gt;previous&lt;/code&gt;&lt;/a&gt; function to find the first previous hidden field relative to the link that called the function which is the _destroy field and sets its value to &lt;code&gt;1&lt;/code&gt; so that the answer will be marked as deleted. It then uses &lt;a href="http://api.prototypejs.org/dom/element.html#up-class_method"&gt;&lt;code&gt;up&lt;/code&gt;&lt;/a&gt; to work its way up the DOM tree from the link until it finds an element with a class of &lt;code&gt;fields&lt;/code&gt;, which is the class name we gave to the paragraph element that wraps the answers fields, and hides it so that the answer is hidden.&lt;/p&gt;

&lt;p&gt;If we reload the survey page now we&amp;rsquo;ll see a link against each answer.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/301/original/E197I02.png" width="816" height="471" alt="The &amp;ldquo;remove&amp;rdquo; checkboxes have now been replaced by links"/&gt;
&lt;/div&gt;

&lt;p&gt;If we click some of the links the value of the &lt;code&gt;_destroy&lt;/code&gt; hidden field will be set to &lt;code&gt;1&lt;/code&gt; for those answers so that they are marked to be deleted and the their form fields are  hidden.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/302/original/E197I03.png" width="816" height="471" alt="The answers are hidden when we click the &amp;ldquo;remove&amp;rdquo; link."/&gt;
&lt;/div&gt;

&lt;p&gt;Note though that we&amp;rsquo;re not using AJAX to post back updated form values when the link is clicked so that although we&amp;rsquo;re hiding the removed answers immediately the database won&amp;rsquo;t be updated until we submit the form. When we do submit the form the answers will be removed and we&amp;rsquo;ll see so on the survey&amp;rsquo;s &lt;code&gt;show&lt;/code&gt; page.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/303/original/E197I04.png" width="816" height="471" alt="The answers have now been removed."/&gt;
&lt;/div&gt;

&lt;h3&gt;Removing Questions&lt;/h3&gt;

&lt;p&gt;Now that we can remove answers through links we&amp;rsquo;ll move on to the questions. The way to remove a question is basically the same as the way we remove an answer and so we can reuse some of the code we wrote earlier.&lt;/p&gt;

&lt;p&gt;As we did with the answers we&amp;rsquo;re going to replace a checkbox and a label with a hidden field and a link so we&amp;rsquo;ll take that part of the code from the &lt;code&gt;answer_fields&lt;/code&gt; partial and put it in a new helper method called &lt;code&gt;link_to_remove_fields&lt;/code&gt;, passing in the text we want to appear in the link and the form variable &lt;code&gt;f&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/surveys/_answer_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;p class=&amp;quot;fields&amp;quot;&amp;gt;
  &amp;lt;%= f.label :content, &amp;quot;Answer&amp;quot; %&amp;gt;
  &amp;lt;%= f.text_field :content %&amp;gt;
  &amp;lt;%= link_to_remove_fields &amp;quot;remove&amp;quot;, f %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ll now write that method in the &lt;code&gt;application_helper&lt;/code&gt; file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/helpers/application_helper.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
  def link_to_remove_fields(name, f)
    f.hidden_field(:_destroy) + link_to_function(name, &amp;quot;remove_fields(this)&amp;quot;)
  end
end
&lt;/pre&gt;
&lt;p&gt;The methods that create form fields return strings, so we can concatenate the HTML generated by &lt;code&gt;f.hidden_field&lt;/code&gt; and &lt;code&gt;link_to_function&lt;/code&gt; methods and return them to the partial.&lt;/p&gt;

&lt;p&gt;We can use our new method in the &lt;code&gt;question_fields&lt;/code&gt; partial too.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/surveys/_question_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;div class=&amp;quot;fields&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :content, &amp;quot;Question&amp;quot; %&amp;gt;
    &amp;lt;%= link_to_remove_fields &amp;quot;remove&amp;quot;, f%&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_area :content, :rows =&amp;gt; 3 %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% f.fields_for :answers do |builder| %&amp;gt;
    &amp;lt;%= render &amp;#x27;answer_fields&amp;#x27;, :f =&amp;gt; builder %&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;As our JavaScript &lt;code&gt;remove_fields&lt;/code&gt; function looks for an element with a class of &lt;code&gt;fields&lt;/code&gt; when hiding a question or answer we&amp;rsquo;ve wrapped the whole partial in a &lt;code&gt;div&lt;/code&gt; element with that class name so that when the &amp;ldquo;remove&amp;rdquo; link for a question is clicked the question will be hidden along with its answers.&lt;/p&gt;

&lt;p&gt;If we look at the &lt;code&gt;edit&lt;/code&gt; page for a survey now and click the a question&amp;rsquo;s &amp;ldquo;remove&amp;rdquo; link the question will be removed along with its answers and when we submit the form the question and its answers will be removed from the survey.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/304/original/E197I05.png" width="815" height="423" alt="The question has been removed along with its answers."/&gt;
&lt;/div&gt;

&lt;h3&gt;Adding Questions and Answers&lt;/h3&gt;

&lt;p&gt;Now for the difficult part: adding new questions and answers. We want links on the form that will create new form fields dynamically when they are clicked. What makes this difficult is that the JavaScript will need to have access to a blank set of fields so that it can create a new question or answer when a link is clicked.&lt;/p&gt;

&lt;p&gt;To do this we&amp;rsquo;ll write a new method in the application helper called &lt;code&gt;link_to_add_fields&lt;/code&gt;.
We&amp;rsquo;ll be able to use this method whenever we need to show a link to add the fields for a new question or answer on the form. The code for the method will look like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/helpers/application_helper.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
def link_to_add_fields(name, f, association)
  new_object = f.object.class.reflect_on_association(association).klass.new
  fields = f.fields_for(association, new_object, :child_index =&amp;gt; &amp;quot;new_#{association}&amp;quot;) do |builder|
    render(association.to_s.singularize + &amp;quot;_fields&amp;quot;, :f =&amp;gt; builder)
  end
  link_to_function(name, h(&amp;quot;add_fields(this, \&amp;quot;#{association}\&amp;quot;, \&amp;quot;#{escape_javascript(fields)}\&amp;quot;)&amp;quot;))
end
&lt;/pre&gt;
&lt;p&gt;The method takes three arguments: &lt;code&gt;name&lt;/code&gt;, which will be the link&amp;rsquo;s text; &lt;code&gt;f&lt;/code&gt;, the form builder object and &lt;code&gt;association&lt;/code&gt;, which in this case will be either &amp;ldquo;questions&amp;rdquo; or &amp;ldquo;answers&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;The first line of the method creates a new instance of that new association class, i.e. a new &lt;code&gt;Question&lt;/code&gt; or &lt;code&gt;Answer&lt;/code&gt;. This means that we have a template object that we can use to create the new form fields.&lt;/p&gt;

&lt;p&gt;The second part of the code builds a string of the form fields for that object so that we can insert them into the javascript function that will add them to the form when a link is clicked. It does this by calling the appropriate partial code, passing in the form builder. The only really new thing here is the &lt;code&gt;:child_index&lt;/code&gt; we set. We do this so that we have something to refer to for creating the fields for the new question or answer. In the JavaScript we&amp;rsquo;ll replace the name of this with a unique value which will be based on the current time. That way, every time we create a new question or answer it will have a unique index so that it can be identified when we submit the form.&lt;/p&gt;

&lt;p&gt;Finally we use the &lt;code&gt;link_to_function&lt;/code&gt; method again, passing in the name of the link and a call to a JavaScript function called &lt;code&gt;add_fields&lt;/code&gt; to which we pass the link, the name of the association and a string containing the escaped form fields.&lt;/p&gt;

&lt;p&gt;Now we can go back to the JavaScript and write the &lt;code&gt;add_fields&lt;/code&gt; function.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/public/javascripts/application.js&lt;/p&gt;
&lt;pre class="javascript"&gt;
function add_fields(link, association, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp(&amp;quot;new_&amp;quot; + association, &amp;quot;g&amp;quot;);
  $(link).up().insert({
	before: content.replace(regexp, new_id)
  });
}
&lt;/pre&gt;
&lt;p&gt;This function takes the three arguments we mentioned earlier: the link that was clicked, the name of the association and a string containing the HTML for the form fields. The first thing this function does is create a new id for the form elements. If we create multiple new questions or answers we don&amp;rsquo;t want them to have the same index value as they will be considered the same model when they&amp;rsquo;re inserted. We use the current time to make the id unique and then use a regular expression to replace the &amp;ldquo;new_question&amp;rdquo; or &amp;ldquo;new_answer&amp;rdquo; string in the form fields with that new unique id. That done we insert the string of form fields into the appropriate place in the DOM.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s the difficult part over. All we need to do now is add the links themselves. In the &lt;code&gt;question_fields&lt;/code&gt; partial we&amp;rsquo;ll add a link to add a new answer using &lt;code&gt;link_to_add_fields&lt;/code&gt;, passing in :answers as the name of the association as a question has many answers.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/surveys/_question_fields.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;div class=&amp;quot;fields&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :content, &amp;quot;Question&amp;quot; %&amp;gt;
    &amp;lt;%= link_to_remove_fields &amp;quot;remove&amp;quot;, f %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_area :content, :rows =&amp;gt; 3 %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% f.fields_for :answers do |builder| %&amp;gt;
    &amp;lt;%= render &amp;#x27;answer_fields&amp;#x27;, :f =&amp;gt; builder %&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= link_to_add_fields &amp;quot;Add Answer&amp;quot;, f, :answers %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We can then to do a similar thing in the survey form to add an &amp;ldquo;Add Question&amp;rdquo; link.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/surveys/_form.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @survey do |f| %&amp;gt;
  &amp;lt;%= f.error_messages %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% f.fields_for :questions do |builder| %&amp;gt;
    &amp;lt;%= render &amp;#x27;question_fields&amp;#x27;, :f =&amp;gt; builder %&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= link_to_add_fields &amp;quot;Add Question&amp;quot;, f, :questions %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= f.submit &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If we reload the survey page now we&amp;rsquo;ll see the links for adding a new question or answer and when we click one of them a new field will appear on the form.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/305/original/E197I06.png" width="800" height="546" alt="A new blank field appears when we click the &amp;ldquo;Add Answer&amp;rdquo; link."/&gt;
&lt;/div&gt;
&lt;p class="title"&gt;A new, blank answer field appears on the form when we click the &amp;ldquo;Add Answer&amp;rdquo; link.&lt;/p&gt;

&lt;p&gt;If we fill in the new answer field above with &amp;ldquo;jQuery&amp;rdquo; and submit the form then the new answer will be added.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/306/original/E197I07.png" width="801" height="375" alt="The new question has now been added"/&gt;
&lt;/div&gt;

&lt;p&gt;So, we&amp;rsquo;ve reached our goal and now have a form on which we can dynamically add or remove fields and have the database updated appropriately when the form is submitted.&lt;/p&gt;

&lt;h3&gt;Alternate jQuery Code&lt;/h3&gt;

&lt;p&gt;The JavaScript code we&amp;rsquo;ve used in this episode works with the Prototype library. If you prefer using jQuery, the code should look like this:&lt;/p&gt;
&lt;pre class="javascript"&gt;
function remove_fields(link) {
	$(link).prev(&amp;quot;input[type=hidden]&amp;quot;).val(&amp;quot;1&amp;quot;);
	$(link).closest(&amp;quot;.fields&amp;quot;).hide();
}

function add_fields(link, association, content) {
	var new_id = new Date().getTime();
	var regexp = new RegExp(&amp;quot;new_&amp;quot; + association, &amp;quot;g&amp;quot;);
	$(link).parent().before(content.replace(regexp, new_id));
}
&lt;/pre&gt;
&lt;p&gt;This code is very similar to the Prototype code we&amp;rsquo;ve been writing.&lt;/p&gt;

&lt;p&gt;Some of you reading this might be a little upset that the JavaScript we&amp;rsquo;ve use isn&amp;rsquo;t unobtrusive. While an unobtrusive solution is always preferable there isn&amp;rsquo;t really one for our problem that was simple enough to present in this episode.  Ryan Bates is working on a plugin called &lt;a href="http://github.com/ryanb/nested_form"&gt;nested_form&lt;/a&gt; that will make use of jQuery to handle nested forms in an unobtrusive way. This plugin is still in early development so if you think you&amp;rsquo;ll need something like this keep checking there to see how it is coming along.&lt;/p&gt;</description>
      <pubDate>Fri, 22 Jan 2010 23:13:17 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/197-nested-model-form-part-2</guid>
      <link>http://asciicasts.com/episodes/197-nested-model-form-part-2</link>
    </item>
    <item>
      <title>Nested Model Form Part 1</title>
      <description>&lt;p&gt;Back in 2007 a &lt;a href="http://railscasts.com/episodes/73-complex-forms-part-1"&gt;series of episodes&lt;/a&gt; covered the creation of complex forms that could manage multiple models in a single form. That series is now rather out of date so beginning with this episode we&amp;rsquo;ll show you the more modern techniques for handling forms with multiple models.&lt;/p&gt;

&lt;p&gt;One thing that makes a big difference in our approach to handling this problem is the &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html"&gt;&lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; method&lt;/a&gt; which was added in Rails 2.3. We&amp;rsquo;ll be using it throughout this series so you&amp;rsquo;ll need to be running the latest version of Rails to make use of this technique in your own applications.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html"&gt;documentation&lt;/a&gt; for &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; is worth reading and shows how to use it with nested attributes in a single update call but it less clear on how we would get this working in the view itself, so we&amp;rsquo;ll focus on this.&lt;/p&gt;

&lt;h3&gt;Our Survey Application&lt;/h3&gt;

&lt;p&gt;Let&amp;rsquo;s first take a look at the application we want to build over the course of this series, which is an application for making surveys. The application will have a complex form for creating and editing surveys that lets us enter a survey&amp;rsquo;s name along with a number of questions, each with multiple answers. The form will also have links to allow us to dynamically add and remove questions and answers from a survey.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/290/original/E196I01.png" width="815" height="598" alt="The complex form for creating and editing surveys." /&gt;
&lt;/div&gt;
&lt;p class="title"&gt;The complex form for creating and editing surveys.&lt;/p&gt;

&lt;p&gt;What we have here is a deeply-nested association in which a survey has many questions and a question many answers. In the previous series on complex forms it was not possible to have create deeply nested forms like this but with Rails 2.3 we can.&lt;/p&gt;

&lt;h3&gt;Getting Started&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;re going to create our survey application from scratch, so we&amp;rsquo;ll start by creating a new Rails application called &lt;code&gt;surveysays&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails surveysays
&lt;/pre&gt;
&lt;p&gt;To make writing the application easier we&amp;rsquo;ll use two of &lt;a href="http://github.com/ryanb/nifty-generators"&gt;Ryan Bates&amp;rsquo; nifty generators&lt;/a&gt;. We&amp;rsquo;ll use the nifty layout generator first to create a layout for the application.&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate nifty_layout
&lt;/pre&gt;
&lt;p&gt;Our application will have three models: &lt;code&gt;Survey&lt;/code&gt;, &lt;code&gt;Question&lt;/code&gt; and &lt;code&gt;Answer&lt;/code&gt;. We&amp;rsquo;ll start with the &lt;code&gt;Survey&lt;/code&gt; model and use the nifty scaffold generator to create a scaffold to go with it. &lt;code&gt;Survey&lt;/code&gt; will have just one attribute called &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate nifty_scaffold survey name:string
&lt;/pre&gt;
&lt;p&gt;Next we&amp;rsquo;ll run the migrations to create the surveys table in the database.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rake db:migrate
&lt;/pre&gt;
&lt;p&gt;If we look at the application now we&amp;rsquo;ll have scaffold files to allow us to list, create and edit surveys and a basic survey form that we can build on.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/291/original/E196I02.png" width="800" height="343" alt="The scaffold-generated basic survey form."/&gt;
&lt;/div&gt;

&lt;p&gt;What we want on the form are fields that will allow us to add questions and answers when we create a new survey. The first step we&amp;rsquo;ll take is to generate the &lt;code&gt;Question&lt;/code&gt; model. This will have a &lt;code&gt;survey_id&lt;/code&gt; field and a content field to hold the question&amp;rsquo;s text.&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate model question survey_id:integer content:text
&lt;/pre&gt;
&lt;p&gt;Having done that we&amp;rsquo;ll migrate the database again to create the &lt;code&gt;questions&lt;/code&gt; table.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rake db:migrate
&lt;/pre&gt;
&lt;p&gt;Next we&amp;rsquo;ll set up the relationship between &lt;code&gt;Survey&lt;/code&gt; and &lt;code&gt;Question&lt;/code&gt; in their model files.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/models/question.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Question &amp;lt; ActiveRecord::Base
  belongs_to :survey
end
&lt;/pre&gt;
&lt;pre class="codeFilePath"&gt;
/app/models/survey.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Survey &amp;lt; ActiveRecord::Base
  has_many :questions, :dependent =&amp;gt; :destroy
end
&lt;/pre&gt;
&lt;p&gt;Note that in &lt;code&gt;Survey&lt;/code&gt; we&amp;rsquo;ve used &lt;code&gt;:dependent =&amp;gt; :destroy&lt;/code&gt; so that when we delete a survey all of its questions are deleted too.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;Survey&lt;/code&gt; model we&amp;rsquo;re going to use &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; so that we can manage questions through &lt;code&gt;Survey&lt;/code&gt;. By using this we can create, update and destroy questions when we update a survey&amp;rsquo;s attributes.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/models/survey.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
  class Survey &amp;lt; ActiveRecord::Base
    has_many :questions, :dependent =&amp;gt; :destroy
    accepts_nested_attributes_for :questions
  end
&lt;/pre&gt;
&lt;h3&gt;Creating The Form&lt;/h3&gt;

&lt;p&gt;Having set up the &lt;code&gt;Survey&lt;/code&gt; and &lt;code&gt;Question&lt;/code&gt; models we&amp;rsquo;ll move on to the survey form. What we want to do here is add fields for each of the survey&amp;rsquo;s questions to the form. We can use the &lt;code&gt;fields_for&lt;/code&gt; method to manage associated fields in a form, passing it the name of the associated model and then loop through all of the associated question records and create a form builder for each of them. The builder will render a label and textarea for each question.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/survey/_form.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @survey do |f| %&amp;gt;
  &amp;lt;%= f.error_messages %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% f.fields_for :questions do |builder| %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= builder.label :content, &amp;quot;Question&amp;quot; %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= builder.text_area :content, :rows =&amp;gt; 3 %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= f.submit &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;When we reload the form now it will look like it did before. This is because a new survey won&amp;rsquo;t have any questions associated with it and therefore none of the question fields will be shown. Ultimately we want to have an &amp;ldquo;Add Question&amp;rdquo; link on the form but for now we&amp;rsquo;ll just create some questions in the &lt;code&gt;SurveyController&lt;/code&gt;&amp;rsquo;s new action.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/controllers/surveys_controller.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
def new
  @survey = Survey.new
  3.times { @survey.questions.build }
end
&lt;/pre&gt;
&lt;p&gt;This will add three questions to a new survey that we&amp;rsquo;ll see in the form when we reload the page. We can now fill in the name and the first two questions and submit a new survey.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/292/original/E196I03.png" width="800" height="570" alt="Filling in the new survey form."/&gt;
&lt;/div&gt;

&lt;p&gt;When we submit the survey a new &lt;code&gt;Survey&lt;/code&gt; record will be created but we won&amp;rsquo;t see its questions as we&amp;rsquo;re not displaying them on the page. To fix this we can modify the &lt;code&gt;show&lt;/code&gt; view for &lt;code&gt;Survey&lt;/code&gt; to show a survey&amp;rsquo;s questions.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/293/original/E196I04.png" width="800" height="320" alt="The questions aren't shown on the survey page."/&gt;
&lt;/div&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/survey/show.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% title &amp;quot;Survey&amp;quot; %&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Name:&amp;lt;/strong&amp;gt;
  &amp;lt;%=h @survey.name %&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;ol&amp;gt;
  &amp;lt;% for question in @survey.questions %&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;%= h question.content %&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/ol&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;%= link_to &amp;quot;Edit&amp;quot;, edit_survey_path(@survey) %&amp;gt; |
  &amp;lt;%= link_to &amp;quot;Destroy&amp;quot;, @survey, :confirm =&amp;gt; &amp;#x27;Are you sure?&amp;#x27;, :method =&amp;gt; :delete %&amp;gt; |
  &amp;lt;%= link_to &amp;quot;View All&amp;quot;, surveys_path %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;When we reload the survey&amp;rsquo;s page we&amp;rsquo;ll see the questions listed which shows that when we added the survey its questions were saved too.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/294/original/E196I05.png" width="800" height="338" alt="The questions are now shown."/&gt;
&lt;/div&gt;

&lt;p&gt;We can also edit a survey and if we change any of the questions they will be updated when we submit the form.&lt;/p&gt;

&lt;p&gt;On the page above we have three questions listed even though we only entered values for the first two. It would be better if blank questions were automatically removed. The &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; method has a &lt;code&gt;reject_if&lt;/code&gt; option that we can use to do this. The method accepts a &lt;code&gt;lambda&lt;/code&gt; which has a hash of attributes passed to it and we can use that hash to reject a question if its &lt;code&gt;content&lt;/code&gt; is blank.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/models/survey.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Survey &amp;lt; ActiveRecord::Base
  has_many :questions, :dependent =&amp;gt; :destroy
  accepts_nested_attributes_for :questions, :reject_if =&amp;gt; lambda { |a| a[:content].blank? }
end
&lt;/pre&gt;
&lt;p&gt;If we create a new survey now with only two of question fields filled in only two questions will be created and we won&amp;rsquo;t see a blank question in the list.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/295/original/E196I06.png" width="800" height="363" alt="Blank questions are no longer shown."/&gt;
&lt;/div&gt;

&lt;p&gt;What if we want to delete existing questions when we&amp;rsquo;re editing a survey? In the final application we want to use a link to delete questions but for now we&amp;rsquo;re going to take the easier option and use a checkbox. In the survey form partial we&amp;rsquo;ll add a checkbox and a label to go with it.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/survey/_form.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @survey do |f| %&amp;gt;
  &amp;lt;%= f.error_messages %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% f.fields_for :questions do |builder| %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= builder.label :content, &amp;quot;Question&amp;quot; %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= builder.text_area :content, :rows =&amp;gt; 3 %&amp;gt;
    &amp;lt;%= builder.check_box :_destroy %&amp;gt;
    &amp;lt;%= builder.label :_destroy, &amp;quot;Remove Question&amp;quot; %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= f.submit &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The trick here is the attribute name for the checkbox: &lt;code&gt;_destroy&lt;/code&gt;. When this has a value of &lt;code&gt;true&lt;/code&gt;, i.e. when the checkbox is checked, the record will be removed when the form is submitted.&lt;/p&gt;

&lt;p&gt;In order to make this work we need to enable it in &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; in the &lt;code&gt;Survey&lt;/code&gt; model by adding &lt;code&gt;:allow_destroy =&amp;gt; true&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/apps/models/survey.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Survey &amp;lt; ActiveRecord::Base
  has_many :questions, :dependent =&amp;gt; :destroy
  accepts_nested_attributes_for :questions, :reject_if =&amp;gt; lambda { |a| a[:content].blank? }, :allow_destroy =&amp;gt; true
end
&lt;/pre&gt;
&lt;p&gt;When we reload the page now we&amp;rsquo;ll have a &amp;ldquo;Remove Question&amp;rdquo; checkbox against each question.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/296/original/E196I07.png" width="815" height="529" alt="We now have checkboxes so that we can remove questions."/&gt;
&lt;/div&gt;
 
&lt;p&gt;And if we check the &amp;ldquo;Remove Question&amp;rdquo; checkbox against one of the questions and submit the form that question will be removed.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/297/original/E196I08.png" width="800" height="356" alt="The question has been succesfully removed."/&gt;
&lt;/div&gt;

&lt;h3&gt;Adding Answers&lt;/h3&gt;

&lt;p&gt;We now have the questions set up as we want them but not the answers. We&amp;rsquo;ll start on that now by creating the &lt;code&gt;Answer&lt;/code&gt; model and setting up the nesting. First we&amp;rsquo;ll generate the model.&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate model answer question_id:integer content:string
&lt;/pre&gt;
&lt;p&gt;Then migrate the database again.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rake db:migrate
&lt;/pre&gt;
&lt;p&gt;Next we&amp;rsquo;ll set up the relationship between &lt;code&gt;Answer&lt;/code&gt; and &lt;code&gt;Question&lt;/code&gt;. &lt;code&gt;Answer&lt;/code&gt; will &lt;code&gt;belong_to&lt;/code&gt; &lt;code&gt;Question&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/models/answer.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Answer &amp;lt; ActiveRecord::Base
  belongs_to :question
end
&lt;/pre&gt;

&lt;p&gt;For &lt;code&gt;Question&lt;/code&gt; we&amp;rsquo;ll need to use &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; as we did in the &lt;code&gt;Survey&lt;/code&gt; model.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/models/question.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
class Question &amp;lt; ActiveRecord::Base
  belongs_to :survey
  has_many :answers, :dependent =&amp;gt; :destroy
  accepts_nested_attributes_for :answers, :reject_if =&amp;gt; lambda { |a| a[:content].blank? }, :allow_destroy =&amp;gt; true
end
&lt;/pre&gt;
&lt;p&gt;In the form we&amp;rsquo;ll need to add fields for answers but the form view code will become cluttered if we add another nested model to it. Later on we&amp;rsquo;ll want to add questions on the form via a link with JavaScript so for both these reasons we&amp;rsquo;ll move the form code that renders each question into a partial called &lt;code&gt;question_fields&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After doing this the form view will look like this.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/surveys/_form.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @survey do |f| %&amp;gt;
  &amp;lt;%= f.error_messages %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;% f.fields_for :questions do |builder| %&amp;gt;
    &amp;lt;%= render &amp;#x27;question_fields&amp;#x27;, :f =&amp;gt; builder %&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= f.submit &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Note that we&amp;rsquo;re just passing the name of the partial as a string to render, making use of the new short form that was introduced in Rails 2.3. We also pass the &lt;code&gt;builder&lt;/code&gt; to the partial with a name of &lt;code&gt;f&lt;/code&gt;. In the new &lt;code&gt;question_fields&lt;/code&gt; partial we can then use that &lt;code&gt;f&lt;/code&gt; variable to render the form elements for a &lt;code&gt;Question&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/surveys/_question_fields.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :content, &amp;quot;Question&amp;quot; %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;%= f.text_area :content, :rows =&amp;gt; 3 %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;%= f.check_box :_destroy %&amp;gt;
  &amp;lt;%= f.label :_destroy, &amp;quot;Remove Question&amp;quot; %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We can handle the answer fields in a similar way and put them in their own partial file. In the &lt;code&gt;_question_fields&lt;/code&gt; partial we&amp;rsquo;ll loop through the answers for the question and render a new partial called &lt;code&gt;_answer_fields&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/surveys/_question_fields.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :content, &amp;quot;Question&amp;quot; %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;%= f.text_area :content, :rows =&amp;gt; 3 %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;%= f.check_box :_destroy %&amp;gt;
  &amp;lt;%= f.label :_destroy, &amp;quot;Remove Question&amp;quot; %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;% f.fields_for :answers do |builder| %&amp;gt;
  &amp;lt;%= render &amp;#x27;answer_fields&amp;#x27;, :f =&amp;gt; builder %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;In our new &lt;code&gt;_answer_fields&lt;/code&gt; partial we&amp;rsquo;ll put the code to render an &lt;code&gt;Answer&lt;/code&gt;.&lt;/p&gt;  
&lt;pre class="codeFilePath"&gt;
/app/views/survey/_answer_fields.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= f.label :content, &amp;quot;Answer&amp;quot; %&amp;gt;
  &amp;lt;%= f.text_field :content %&amp;gt;
  &amp;lt;%= f.check_box :_destroy %&amp;gt;
  &amp;lt;%= f.label :_destroy, &amp;quot;Remove&amp;quot; %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;So that we can see the answer fields on the form we&amp;rsquo;ll modify the &lt;code&gt;SurveyController&lt;/code&gt;&amp;rsquo;s &lt;code&gt;new&lt;/code&gt; action so that the three new questions that are created each create four answers.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/controllers/survey_controller.rb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
def new
  @survey = Survey.new
  3.times do
    question = @survey.questions.build
    4.times { question.answers.build }
  end
end
&lt;/pre&gt;
&lt;p&gt;Now, when we create a survey we have three questions each with four answers.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/298/original/E196I09.png" width="815" height="509" alt="Answer fields are now shown in the survey form."/&gt;
&lt;/div&gt;

&lt;p&gt;When we fill in the fields and submit the form the answers won&amp;rsquo;t be shown but we can easily fix that. In the section of the &lt;code&gt;show&lt;/code&gt; view for a survey that renders each question we&amp;rsquo;ll add some code to render each question&amp;rsquo;s answers.&lt;/p&gt;
&lt;pre class="codeFilePath"&gt;
/app/views/survey/show.html.erb
&lt;/pre&gt;
&lt;pre class="ruby"&gt;
&amp;lt;ol&amp;gt;
  &amp;lt;% for question in @survey.questions %&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;%= h question.content %&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;% for answer in question.answers %&amp;gt;
      &amp;lt;li&amp;gt;&amp;lt;%= h answer.content %&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;% end %&amp;gt;
  &amp;lt;/ul&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/ol&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If we reload the survey&amp;rsquo;s page now it will show the questions and the answers.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/299/original/E196I10.png" width="815" height="509" alt="The answers are now displayed underneath their questions."/&gt;
&lt;/div&gt;

&lt;p&gt;We aren&amp;rsquo;t quite done yet as we want to be able to add or remove questions or answers on the form dynamically via links. We&amp;rsquo;ll cover this in the next episode.&lt;/p&gt;</description>
      <pubDate>Thu, 14 Jan 2010 22:26:59 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/196-nested-model-form-part-1</guid>
      <link>http://asciicasts.com/episodes/196-nested-model-form-part-1</link>
    </item>
    <item>
      <title>Favourite Web Apps in 2009</title>
      <description>&lt;p&gt;This week&amp;rsquo;s episode will be a little different from normal in that we&amp;rsquo;re going to show you some of the best web applications for Rails developers in 2009. All of the following applications will help you improve your Rails apps in some way or other. Let&amp;rsquo;s jump straight in with the first one.&lt;/p&gt;

&lt;h3&gt;Github&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/281/original/E195I01.png" width="839" height="593" alt="The Github home page."/&gt;
&lt;/div&gt;

&lt;p&gt;The first app on the list should require no introduction: &lt;a href="http://github.com/"&gt;Github&lt;/a&gt;. If you&amp;rsquo;re a programmer then you really should be using it. Github has several features that are less well-known but still useful, for example &lt;a href="http://gist.github.com"&gt;Gists&lt;/a&gt; which are handy ways to share code snippets. Github&amp;rsquo;s help section is also worth taking a look as it contains a wealth of articles to help you get the most from Git and Github.&lt;/p&gt;

&lt;h3&gt;Gemcutter&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/282/original/E195I02.png" width="824" height="597" alt="The Gemcutter home page."/&gt;
&lt;/div&gt;

&lt;p&gt;The second app in our list is &lt;a href="http://gemcutter.org/"&gt;Gemcutter&lt;/a&gt; which is the ultimate place to host your RubyGems. Gemcutter was covered back in episode 183 [&lt;a href="http://railscasts.com/episodes/183-gemcutter-jeweler"&gt;watch&lt;/a&gt;, &lt;a href="http://asciicasts.com/episodes/183-gemcutter-jeweler"&gt;read&lt;/a&gt;], but since then it has become even easier to use. Previously you had to call the &lt;code&gt;gem tumble&lt;/code&gt; command to install gems from Gemcutter but this is no longer necessary as the gem hosting on RubyForge now points to Gemcutter making it the best place to install Gems from.&lt;/p&gt; 

&lt;p&gt;What makes Gemcutter so valuable is the ease with which it allows you to publish your own gems. It takes just the three steps listed in the screenshot above. The only potentially tricky part is creating a &lt;code&gt;gemspec&lt;/code&gt; file but that can be made easier by using another gem&amp;rsquo;s gemspec file as a template. A good example is the &lt;a href="http://github.com/ryanb/cancan/blob/master/cancan.gemspec"&gt;gemspec file for Ryan Bates&amp;rsquo; CanCan gem&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="ruby"&gt;
Gem::Specification.new do |s|
&amp;nbsp;&amp;nbsp;s.name = &amp;quot;cancan&amp;quot;
&amp;nbsp;&amp;nbsp;s.summary = &amp;quot;Simple authorization solution for Rails.&amp;quot;
&amp;nbsp;&amp;nbsp;s.description = &amp;quot;Simple authorization solution for Rails which is completely decoupled from the user&amp;#x27;s roles. All permissions are stored in a single location for convenience.&amp;quot;
&amp;nbsp;&amp;nbsp;s.homepage = &amp;quot;http://github.com/ryanb/cancan&amp;quot;
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;s.version = &amp;quot;1.0.2&amp;quot;
&amp;nbsp;&amp;nbsp;s.date = &amp;quot;2009-12-30&amp;quot;
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;s.authors = [&amp;quot;Ryan Bates&amp;quot;]
&amp;nbsp;&amp;nbsp;s.email = &amp;quot;ryan@railscasts.com&amp;quot;
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;s.require_paths = [&amp;quot;lib&amp;quot;]
&amp;nbsp;&amp;nbsp;s.files = Dir[&amp;quot;lib/**/*&amp;quot;] + Dir[&amp;quot;spec/**/*&amp;quot;] + [&amp;quot;LICENSE&amp;quot;, &amp;quot;README.rdoc&amp;quot;, &amp;quot;Rakefile&amp;quot;, &amp;quot;CHANGELOG.rdoc&amp;quot;, &amp;quot;init.rb&amp;quot;]
&amp;nbsp;&amp;nbsp;s.extra_rdoc_files = [&amp;quot;README.rdoc&amp;quot;, &amp;quot;CHANGELOG.rdoc&amp;quot;, &amp;quot;LICENSE&amp;quot;]
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;s.has_rdoc = true
&amp;nbsp;&amp;nbsp;s.rdoc_options = [&amp;quot;--line-numbers&amp;quot;, &amp;quot;--inline-source&amp;quot;, &amp;quot;--title&amp;quot;, &amp;quot;CanCan&amp;quot;, &amp;quot;--main&amp;quot;, &amp;quot;README.rdoc&amp;quot;]
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;s.rubygems_version = &amp;quot;1.3.4&amp;quot;
&amp;nbsp;&amp;nbsp;s.required_rubygems_version = Gem::Requirement.new(&amp;quot;&amp;gt;= 1.2&amp;quot;)
end
&lt;/pre&gt;
&lt;p&gt;A gemspec file like the one above can be edited to suit your own project. The file is easy to change directly whenever you create a new version of your gem and you can then build and push to release the new version.&lt;/p&gt;

&lt;h3&gt;Caliper&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/283/original/E195I03.png" width="824" height="597" alt="The Caliper home page."/&gt;
&lt;/div&gt;

&lt;p&gt;Next up is &lt;a href="http://getcaliper.com"&gt;Caliper&lt;/a&gt;. You might remember that back in episode 166 [ &lt;a href="http://railscasts.com/episodes/166-metric-fu"&gt;watch&lt;/a&gt;, &lt;a href="http://asciicasts.com/episodes/166-metric-fu"&gt;read&lt;/a&gt;] we covered the metric_fu gem. Caliper is basically an online version of metric_fu and is a great way to gather metric information about any Rails application that is hosted in a Git repository. To use it you just need to enter the URL of the repository and within a few seconds it will return all of the metric information for that project.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/284/original/E195I04.png" width="832" height="" alt="747"/&gt;
&lt;/div&gt;

&lt;p&gt;You can view information about test/code ratios, code smells and many other details about your Rails applications so that you can help improve your code or use it to examine other projects you&amp;rsquo;re interested in. If you find a gem or plugin you want to use you can run it through Caliper to find out how large the codebase is and how well it has been designed and written.&lt;/p&gt;

&lt;h3&gt;Rdoc.info&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/285/original/E195I05.png" width="819" height="471" alt="The rdoc.info home page."/&gt;
&lt;/div&gt;
&lt;p&gt;Another useful site is &lt;a href="http://rdoc.info/"&gt;rdoc.info&lt;/a&gt;. If you&amp;rsquo;re looking for documentation for a given Ruby project on Github, try this site and look for the project you&amp;rsquo;re interested in. If it&amp;rsquo;s not listed you can add it and the RDocs will be generated and made available.&lt;/p&gt;

&lt;h3&gt;RunCodeRun&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/286/original/E195I06.png" width="808" height="550" alt="The RunCodeRun home page."/&gt;
&lt;/div&gt;

&lt;p&gt;Another great application is &lt;a href="http://runcoderun.com"&gt;RunCodeRun&lt;/a&gt;, which is a simple continuous integration server. Just point it at an application in a Github repository and it will run that app&amp;rsquo;s tests and report back on whether they pass or fail. RunCodeRun is free for public repositories and is well worth trying out. Once it has run the tests you can browse the projects and see which ones pass or fail.&lt;/p&gt;

&lt;p&gt;RunCodeRun uses your application&amp;rsquo;s default rake task to run the tests. This means that you can alter this task to do whatever you want it to. In your application&amp;rsquo;s &lt;code&gt;Rakefile&lt;/code&gt; you could point it to the &lt;code&gt;:spec&lt;/code&gt; and &lt;code&gt;:features&lt;/code&gt; tasks so that the Rspec and Cucumber features are run.&lt;/p&gt;
&lt;pre class="ruby"&gt;
task :default =&amp;gt; [:spec, :features]
&lt;/pre&gt;

&lt;h3&gt;The Ruby Toolbox&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/287/original/E195I07.png" width="851" height="593" alt="The Ruby Toolbox home page."/&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.ruby-toolbox.com"&gt;The Ruby Toolbox&lt;/a&gt; is a great resource. Often when you&amp;rsquo;re developing a new Rails application you&amp;rsquo;re left wondering which gem or plugin to use for a certain task. The Ruby Toolbox is an excellent way to find out which gems or plugins are available for handling different categories of task. For example if your application requires versioning you can find a list of the available projects and how to use them.&lt;/p&gt; 

&lt;h3&gt;New Relic&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/288/original/E195I08.png" width="851" height="593" alt="The New Relic home page."/&gt;
&lt;/div&gt;

&lt;p&gt;Another application that you should be using in any production Rails applications you have is &lt;a href="http://newrelic.com"&gt;NewRelic RPM&lt;/a&gt;. This is a immensely useful application for finding performance issues in your applications to ensure that it&amp;rsquo;s running smoothly and to help keep it that way. Even the free version, RPM Lite, provides enough information to enable to find the bottlenecks in your application and to monitor how well it is running.&lt;/p&gt; 

&lt;h3&gt;Learnivore&lt;/h3&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/289/original/E195I09.png" width="851" height="593" alt="The Learnivore home page."/&gt;
&lt;/div&gt;

&lt;p&gt;If you&amp;rsquo;re a fan of screencasts then &lt;a href="http://www.learnivore.com/search"&gt;Learnivore&lt;/a&gt; is a great site. There are a large number of both free and paid screencasts aggregated there including Railscasts. Learnivore is a resource well worth checking out.&lt;/p&gt;

&lt;p&gt;Finally Ryan kindly mentioned ASCIIcasts as one of his favourite sites but as you&amp;rsquo;re already here you already know all there is to know about it.&lt;/p&gt;</description>
      <pubDate>Tue, 05 Jan 2010 17:07:53 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/195-my-favorite-web-apps-in-2009</guid>
      <link>http://asciicasts.com/episodes/195-my-favorite-web-apps-in-2009</link>
    </item>
    <item>
      <title>MongoDB and MongoMapper</title>
      <description>&lt;p&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Home"&gt;MongoDB&lt;/a&gt; is a document-based database engine which works differently from traditional relational databases such as MySQL in that it is schema-free. This episode will cover the basics of using MongoDB with the &lt;a href="http://mongomapper.com"&gt;MongoMapper gem&lt;/a&gt; to create a simple Rails application. Many Rails developers first heard about MongoDB after a posting by John Nunemaker on his excellent &lt;a href="http://railstips.org/2009/12/18/why-i-think-mongo-is-to-databases-what-rails-was-to-frameworks"&gt;RailsTips blog&lt;/a&gt; showing seven features of MongoMapper and MongoDB that contrast it with traditional relational databases. This post is well worth reading if you think you might be interested in using MongoDB.&lt;/p&gt; 

&lt;p&gt;One feature mentioned in the blog posting and one that makes MongoDB interesting is that you don&amp;rsquo;t need to use migrations as it&amp;rsquo;s basically a schema-less database engine. Each row is its own document which can have its own set of attributes different from the other rows in the database. As there is no fixed schema we can define one on the fly if we want to.&lt;/p&gt;

&lt;h3&gt;Installing MongoDB and MongoMapper&lt;/h3&gt;

&lt;p&gt;To create our application we&amp;rsquo;ll first need to install MongoDB. Downloads for various platforms can be found on the &lt;a href="http://www.mongodb.org/display/DOCS/Downloads"&gt;download page&lt;/a&gt; on the MongoDB site. If you&amp;rsquo;re using OS X there&amp;rsquo;s &lt;a href="http://www.shiftcommathree.com/articles/how-to-install-mongodb-on-os-x"&gt;a great article&lt;/a&gt; on how to install and configure MongoDB on Chris Kampmeier&amp;rsquo;s site. This article includes a handy &lt;code&gt;plist&lt;/code&gt; file that will allow you to create a LaunchDemon  so that MongoDB will run automatically on startup. The article makes a reference to an old version of MongoDB so make sure that you install the latest version instead (1.2.0 at the time of writing). Once MongoDB is installed and configured you can visit &lt;a href="http://localhost:28017/"&gt;http://localhost:28017/&lt;/a&gt; to see if it&amp;rsquo;s working.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/275/original/E194I01.png" width="789" height="385" alt="Testing that MongoDB is running."/&gt;
&lt;/div&gt;

&lt;h3&gt;Creating a Rails Application With MongoDB&lt;/h3&gt;

&lt;p&gt;Now that we have MongoDB installed and running we can start creating a Rails application that will work with it. We&amp;rsquo;ll create a new Rails application from scratch for this episode called &lt;code&gt;todo&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="terminal"&gt;
rails todo
&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ll be using the MongoMapper gem to enable our app to talk to MongoDB. To do this we need to add the following line in the config block of &lt;code&gt;/config/environment.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/environment.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
config.gem &amp;quot;mongo_mapper&amp;quot;
&lt;/pre&gt;
&lt;p&gt;We also need to set up some additional configuration which we&amp;rsquo;ll do inside an initializer file. In the &lt;code&gt;/config/initializers&lt;/code&gt; directory we&amp;rsquo;ll create a new file that we&amp;rsquo;ll call &lt;code&gt;mongo_config.rb&lt;/code&gt;. In this file we just need to add one line to tell MongoMapper which database to use.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/config/initializers/mongo_config.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
MongoMapper.database = &amp;quot;todo-#{Rails.env}&amp;quot;
&lt;/pre&gt;
&lt;p&gt;By passing the current environment as part of the database name we&amp;rsquo;ll create different databases for our development, test and production environments. If we were to move this application into production there&amp;rsquo;d be more we&amp;rsquo;d need to do for authentication and so on but for the purposes of this demonstration what we have is fine.&lt;/p&gt;

&lt;p&gt;The final step in setting up our application is to run the following command to make sure that the MongoMapper gem is installed.&lt;/p&gt;
&lt;pre class="terminal"&gt;
sudo rake gems:install
&lt;/pre&gt;
&lt;h3&gt;Building Our Application&lt;/h3&gt;

&lt;p&gt;Now we can start building our application. This is a simple todo list app which will have a &lt;code&gt;Project&lt;/code&gt; model and where a &lt;code&gt;Project&lt;/code&gt; will have many Tasks. To make the writing of the application easier we&amp;rsquo;ll use Ryan Bates&amp;rsquo; &lt;a href="http://github.com/ryanb/nifty-generators"&gt;Nifty Generators&lt;/a&gt;, but note that the application could be written without them.&lt;/p&gt;

&lt;p&gt;The first thing we&amp;rsquo;ll do is create a layout for our application which we can do by running&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate nifty_layout
&lt;/pre&gt;
&lt;p&gt;Next we&amp;rsquo;ll generate the &lt;code&gt;Project&lt;/code&gt; model and a scaffold to go with it. &lt;code&gt;Project&lt;/code&gt; will have only one field, &lt;code&gt;name&lt;/code&gt;, and as we&amp;rsquo;re not generating a normal model ActiveRecord model with a schema we&amp;rsquo;ll pass &lt;code&gt;--skip-migration&lt;/code&gt; so that no migration file is generated.&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate nifty_scaffold project name:string --skip-migration
&lt;/pre&gt;
&lt;p&gt;This will generate a model file, controller and views for us. The generated &lt;code&gt;Project&lt;/code&gt; model will be an ActiveRecord one so we&amp;rsquo;ll have to change it to work with MongoMapper.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/project.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Project &amp;lt; ActiveRecord::Base
  attr_accessible :name
end
&lt;/pre&gt;
&lt;p class="title"&gt;The generated code for the &lt;code&gt;Project&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;All we have to do here is stop our class inheriting from &lt;code&gt;ActiveRecord::Base&lt;/code&gt; and include &lt;code&gt;MongoMapper::Document&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;To define the model&amp;rsquo;s attributes we use a &lt;code&gt;key&lt;/code&gt; method. We pass this the name of the attribute, in this case &lt;code&gt;:name&lt;/code&gt;, and also a type which should be a Ruby class. For our &lt;code&gt;:name&lt;/code&gt; attribute this will be a &lt;code&gt;String&lt;/code&gt;. Our model will now look like this:&lt;/p&gt;
&lt;p class="codeFilePath"&gt;/app/models/project.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Project
  include MongoMapper::Document

  key :name, String
end
&lt;/pre&gt;
&lt;p&gt;With the changes we&amp;rsquo;ve made to the model we can now run our application and use it to create, update and list projects as we would with an application based on a relational database and ActiveRecord, only instead it&amp;rsquo;s using MongoMapper and MongoDB.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/276/original/E194I02.png" width="801" height="347" alt="Using our application to create a new project."/&gt;
&lt;/div&gt;

&lt;p&gt;In terms of its interface MongoMapper works in a similar way to ActiveRecord. We can perform finds and create, update and destroy records just like we normally would. It even supports validations in the same way as ActiveRecord so we could add&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/project.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
validates_presence_of :name
&lt;/pre&gt;
&lt;p&gt;to our Project model and we would no longer be able to create a project with a blank name. With MongoMapper there&amp;rsquo;s a better way to add validations by moving them inline. To make the name attribute required we can add  &lt;code&gt;:required =&amp;gt; true&lt;/code&gt; to the key method&amp;rsquo;s parameters.&lt;/p&gt;
&lt;p class="codeFilePath"&gt;/app/models/project.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Project
  include MongoMapper::Document

  key :name, String, :required =&amp;gt; true
end
&lt;/pre&gt;
&lt;p class="title"&gt;Adding validation to the &lt;code&gt;Project&lt;/code&gt; model.&lt;/p&gt;

&lt;h3&gt;Adding More Attributes&lt;/h3&gt;

&lt;p&gt;As MongoDB is a schema-less database we can easily add or alter attributes in a model without needing to run any migrations. If we want to add a &lt;code&gt;priority&lt;/code&gt; attribute to our &lt;code&gt;Project&lt;/code&gt; we can just add it into the model.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/project.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Project
  include MongoMapper::Document

  key :name, String, :required =&amp;gt; true
  key :priority, Integer
end
&lt;/pre&gt;
&lt;p&gt;We can interact with this new attribute just as we would with an ActiveRecord one. So, in the &lt;code&gt;Project&lt;/code&gt; form partial we can add a select menu that will allow us to select a priority when we create or update a project.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/projects/_form.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @project do |f| %&amp;gt;
  &amp;lt;%= f.error_messages %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :priority %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.select :priority, [1,2,3,4,5] %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= f.submit &amp;quot;Submit&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We can then modify the &lt;code&gt;show&lt;/code&gt; view so that we can display a project&amp;rsquo;s priority.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/projects/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% title &amp;quot;Project&amp;quot; %&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Name:&amp;lt;/strong&amp;gt;
  &amp;lt;%=h @project.name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Priority:&amp;lt;/strong&amp;gt;
  &amp;lt;%=h @project.priority %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= link_to &amp;quot;Edit&amp;quot;, edit_project_path(@project) %&amp;gt; |
  &amp;lt;%= link_to &amp;quot;Destroy&amp;quot;, @project, :confirm =&amp;gt; &amp;#x27;Are you sure?&amp;#x27;, :method =&amp;gt; :delete %&amp;gt; |
  &amp;lt;%= link_to &amp;quot;View All&amp;quot;, projects_path %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;When we visit the New Project page now we&amp;rsquo;ll see the priority select menu and when we create a new project its priority will be shown.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/277/original/E194I03.png" width="800" height="398" alt="Our new project has a priority."/&gt;
&lt;/div&gt;

&lt;p&gt;As we created a project before we added the &lt;code&gt;priority&lt;/code&gt; attribute you might be wondering what priority it will have assigned to it. If we look at that project we&amp;rsquo;ll see that the priority is blank. As a priority value doesn&amp;rsquo;t exist for that for that document in MongoDB it will have a &lt;code&gt;nil&lt;/code&gt; value.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/278/original/E194I04.png" width="801" height="308" alt="The first project has a blank priority value."/&gt;
&lt;/div&gt;

&lt;h3&gt;Associations&lt;/h3&gt;

&lt;p&gt;In our Todo application we also want to have a &lt;code&gt;Task&lt;/code&gt; model; each &lt;code&gt;Project&lt;/code&gt; will have many &lt;code&gt;Tasks&lt;/code&gt;. We&amp;rsquo;ll generate the scaffolding for this as we did before for &lt;code&gt;Project&lt;/code&gt;. Note that the &lt;code&gt;project_id&lt;/code&gt; is a string where we&amp;rsquo;d usually use an integer.&lt;/p&gt;
&lt;pre class="terminal"&gt;
script/generate nifty_scaffold task project_id:string name:string completed:boolean --skip-migration
&lt;/pre&gt;
&lt;p&gt;As with the &lt;code&gt;Project&lt;/code&gt; model we&amp;rsquo;ll need to modify the model file to work with MongoMapper, by replacing the ActiveRecord-specific code.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/Task.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Task
  include MongoMapper::Document
  
  key :project_id, ObjectId
  key :name, String
  key :completed, Boolean
  
  belongs_to :project
end
&lt;/pre&gt;
&lt;p&gt;Again we&amp;rsquo;ve included &lt;code&gt;MongoMapper::Document&lt;/code&gt; and used the &lt;code&gt;key&lt;/code&gt; method to define the model&amp;rsquo;s attributes. You might have expected the &lt;code&gt;project_id&lt;/code&gt; to have a type of &lt;code&gt;Integer&lt;/code&gt;, but MongoDB uses &lt;code&gt;ObjectId&lt;/code&gt; to store ids.&lt;/p&gt;

&lt;p&gt;We define &lt;code&gt;Task&lt;/code&gt;&amp;rsquo;s relationship with Project as we would with ActiveRecord by using &lt;code&gt;belongs_to&lt;/code&gt;. In &lt;code&gt;Project&lt;/code&gt; you might expect to use &lt;code&gt;has_many :tasks&lt;/code&gt;, but for MongoMapper we instead use &lt;code&gt;many&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/project.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Project
  include MongoMapper::Document

  key :name, String, :required =&amp;gt; true
  key :priority, Integer
  
  many :tasks
end
&lt;/pre&gt;
&lt;p&gt;We can now run the application and use the scaffold-generated controller and views to create new tasks. Entering a project&amp;rsquo;s id on the new task form will be tricky though as the scaffold will have generated a text box for the &lt;code&gt;project_id&lt;/code&gt; field. This is because we defined it as a string field when we created the scaffold. We&amp;rsquo;ll modify the view so that it uses a select menu allowing to choose from any of the existing projects. Just like we would with an ActiveRecord form we can use &lt;code&gt;collection_select&lt;/code&gt; to create a select menu that lists all of the projects.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/tasks/_form.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% form_for @task do |f| %&amp;gt;
  &amp;lt;%= f.error_messages %&amp;gt;
  &amp;lt;p&amp;gt;
    &amp;lt;%= f.label :project_id %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.collection_select :project_id, Project.all, :id, :name %&amp;gt;
  &amp;lt;/p&amp;gt;
  &amp;lt;!-- Rest of form... --&amp;gt;
&lt;/pre&gt;  
&lt;p&gt;Now we&amp;rsquo;ll have an easy way to select a project when we&amp;rsquo;re creating a new task.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/279/original/E194I05.png" width="801" height="433" alt="Using collection_select to create a select menu as we would with ActiveRecord."/&gt;
&lt;/div&gt;

&lt;p&gt;After we&amp;rsquo;ve created a new task we&amp;rsquo;ll be taken to that task&amp;rsquo;s page which will show the project&amp;rsquo;s &lt;code&gt;id&lt;/code&gt;. It would be better if we could show the project&amp;rsquo;s name instead. We can do this by replacing &lt;code&gt;@task.project_id&lt;/code&gt; in the show view with &lt;code&gt;@task.project.name&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/tasks/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;% title &amp;quot;Task&amp;quot; %&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Project:&amp;lt;/strong&amp;gt;
  &amp;lt;%=h @task.project.name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;!-- Rest of form --&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The form will now show the name from the associated project, just as it would with an ActiveRecord-based form.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/280/original/E194I06.png" width="801" height="350" alt="We can see attributes from related models just like with ActiveRecord."/&gt;
&lt;/div&gt;

&lt;h3&gt;Finds in MongoDB&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll finish off this episode by showing a few techniques for using finding Mongo models in the console. In some ways it behaves very much like ActiveRecord. For example we can find all of the projects with &lt;code&gt;Project.all&lt;/code&gt;&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;gt;&amp;gt; Project.all
=&amp;gt; [#&amp;lt;Project name: &amp;quot;Yardwork&amp;quot;, _id: 4b39d8c9a175750357000001, priority: nil&amp;gt;, #&amp;lt;Project name: &amp;quot;Housework&amp;quot;, _id: 4b39fbd1a175750357000002, priority: 3&amp;gt;]
&lt;/pre&gt;
&lt;p&gt;We can also find a project by its &lt;code&gt;id&lt;/code&gt;&amp;hellip;&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;gt;&amp;gt; Project.find(&amp;#x27;4b39d8c9a175750357000001&amp;#x27;)
=&amp;gt; #&amp;lt;Project name: &amp;quot;Yardwork&amp;quot;, _id: 4b39d8c9a175750357000001, priority: nil&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;hellip;or supply options to all to find records in a given order.&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;gt;&amp;gt; Project.all(:order =&amp;gt; &amp;quot;name DESC&amp;quot;)
=&amp;gt; [#&amp;lt;Project name: &amp;quot;Yardwork&amp;quot;, _id: 4b39d8c9a175750357000001, priority: nil&amp;gt;, #&amp;lt;Project name: &amp;quot;Housework&amp;quot;, _id: 4b39fbd1a175750357000002, priority: 3&amp;gt;]
&lt;/pre&gt;
&lt;p&gt;As with ActiveRecord we can pass conditions to &lt;code&gt;find&lt;/code&gt;. This differs from ActiveRecord in that the conditions are passed inline so we would find all of the projects with a priority of 3 with:&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;gt;&amp;gt; Project.all(:priority =&amp;gt; 3)
=&amp;gt; [#&amp;lt;Project name: &amp;quot;Housework&amp;quot;, _id: 4b39fbd1a175750357000002, priority: 3&amp;gt;]
&lt;/pre&gt;
&lt;p&gt;What about more complex conditions? As Mongo isn&amp;rsquo;t based on SQL we can&amp;rsquo;t just pass a SQL string into the conditions. Instead it has its own language for creating more complex conditions. MongoMapper provides a convenient way to get around this by passing a method to a symbol. For example to get all of the projects that have a priority of two or greater we can use:&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;gt;&amp;gt; Project.all(:priority.gte =&amp;gt; 2)
=&amp;gt; [#&amp;lt;Project name: &amp;quot;Housework&amp;quot;, _id: 4b39fbd1a175750357000002, priority: 3&amp;gt;]
&lt;/pre&gt;
&lt;p&gt;We can also use &lt;code&gt;in&lt;/code&gt;, passing it an array of values to find, say, projects with a priority of 2 or 3.&lt;/p&gt;
&lt;pre class="terminal"&gt;
&amp;gt;&amp;gt; Project.all(:priority.in =&amp;gt; [2,3])
=&amp;gt; [#&amp;lt;Project name: &amp;quot;Housework&amp;quot;, _id: 4b39fbd1a175750357000002, priority: 3&amp;gt;]
&lt;/pre&gt;
&lt;p&gt;Documentation is a little sparse on the find conditions right now, but you can find out more about them by reading though the appropriate &lt;a href="http://github.com/jnunemaker/mongomapper/blob/1831798fe3b8b2aea398435a4b1ea6f29f1a63c5/test/test_finder_options.rb"&gt;test file on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it for this episode. We&amp;rsquo;ve only covered the basics of MongoDB and MongoMapper so you&amp;rsquo;re encouraged to do your own research if you want to take it any further. There is a &lt;a href="http://groups.google.com/group/mongodb-user"&gt;mailing list&lt;/a&gt; you can join and you can &lt;a href="http://twitter.com/mongodb"&gt;follow MongoDB on Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The big question you need to ask yourself is should you use MongoDB over a traditional relational database? It&amp;rsquo;s really up to you to decide whether you think MongoDB and MongoMapper are suitable for your Rails projects, but you&amp;rsquo;re encouraged to give MongoDB a try to see if it&amp;rsquo;s a good fit for your projects. In the long term it seems that document databases will play a bigger role in building Rails applications.&lt;/p&gt;</description>
      <pubDate>Wed, 30 Dec 2009 12:43:47 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/194-mongodb-and-mongomapper</guid>
      <link>http://asciicasts.com/episodes/194-mongodb-and-mongomapper</link>
    </item>
  </channel>
</rss>
