Rolling with Ruby on Rails Revisited, Part 2
Pages: 1, 2, 3, 4

CB: Now we have to have the system assign a date whenever someone creates or updates a recipe. That needs to happen in the recipe controller, so I'll open cookbook2\app\controllers\recipe_controller.rb (Figure 17) and add a line to both the create and update methods.



@recipe.date = Time.now

updated recipe controller
Figure 17. Taking over the date assignment in the controller

Done!

CB: OK, Boss. We've added six lines of code. Time to check our work. I modified the model files so I need to restart our web server: mongrel. For performance reasons, even in development mode Rails only reads an application's model files at startup. Whenever we modify a Rails model, we need to restart our web server. To stop Mongrel, in the Command window, I just hit Ctrl-C. Then, to restart it, I enter...

mongrel_rails start

CB: OK, Boss. You ready to do the honors? Point our browser to http://localhost:3000/recipe/new, and ...

Voilá! Date's gone and there's a drop-down list for Category.

Paul: I noticed that in the controller, most of the references were to a variable named @recipe. Here in the form, though, it looks like you're referring to the same object using a different syntax.

CB: You're right, Paul. The text_field statements in the view use a different syntax, but refer to exactly the same object that the controller uses with an instance variable. It can be confusing at first. There's a much more accurate detailed explanation, but here's how I kept it straight when I was getting started. I use an instance variable to push stuff to the user. Any instance variable I create in my controller is automatically available to the view I use for generating the HTML file I'll send back to the visitor's browser. When I need to get information from the visitor, it will come back in something known as the params hash. That's a data structure that gets built in the visitor's browser and sent back when she starts a new request-response cycle. The syntax of text_field, for example, actually helped me remember how to get the data out of the form. If I have a text_field in a form like <%= text_field 'recipe,' 'description,' %> I can access that in the controller with @recipe.description = params[:recipe][:description], or I can present it back to the visitor in another cycle if I want by using @recipe = Recipe.find(the_one_I_want) in the controller, and then using <%= @recipe.description %> in the view. There's more to it than that, of course, but it helped me keep things straight in the beginning.

updated new recipe page
Figure 18. Updated recipe creation page

Go ahead and create a new recipe, Boss. You just fixed us a pizza, so that recipe's probably fresh in your mind ;-)

our first recipe!
Figure 19. Our first recipe!

CB: Starting to get impressed?

Boss: Well, sure. But it doesn't look anything like the original yet. Can we fix that up a little now?

CB: Piece of cake! I see several things that need attention. The recipe display needs a border. The Title column heading needs to change, and the table needs to have a column to display each recipe's category. The consultant's list of requirements says that clicking on a recipe's category will sort the list so that only recipes of that category are shown. That means we need some sort of link on each recipe's category. The screen shot also shows that the instructions should not appear in the listing. The requirements say that the Edit feature will be available from a noneditable view that we reach by clicking on the recipe name. Finally, the screen shot shows that the Show and Destroy links for the recipe need a little rearranging.

Boss: That sounds like a lot of work!

CB: A lot of work on some platforms. Not on Rails. Watch this. I open the cookbook2\app\views\recipes\list.rhtml file (Figure 20). Basically, what it's doing is reading the Recipe model and creating a table with a column for each attribute, putting a table header on each column with the name of the attribute, and then creating rows for each record in our Recipes table.

recipe list view file
Figure 20. Rails-generated recipe list view

CB: We're going to make some pretty major changes here. I need to make it look like this:

<table border="1">
  <tr>
    <th width="60%"><em>Recipe</em</th>
    <th width="20%"><em>Category</em></th>
    <th width="20%"><em>Date</em</th>
  </tr>
 
<% for recipe in @recipes %>
  <tr>
    <td><%= link_to %Q{#{recipe.title}}, :action => 'show', :id => recipe %>
        <%= link_to '(delete)', { :action => 'destroy', :id => recipe },
                               
  :confirm => 'Are you sure?', :post => true %></td>
    <td><%= link_to %Q{#{recipe.category.name}},
                   {:action => 'list', :category_id => recipe.category.id} %></td>
    <td><%=h recipe.date %></td>
  </tr>
<% end %>
</table>

CB: OK. By my count, we just added seven lines of code. Better check our work ;-) Boss, would you refresh the browser?

CB:Hey, Paul. Remember what I was saying about instance variables versus params? See how we use the instance variable @recipes in the for loop? Its value gets set in the controller, and now we're using it in the view to create the list of recipes to display in the page we're sending back to the visitor.

new listing view in browser
Figure 21. Making it pretty

Boss: It looks like we're getting close (Figure 21).

CB: We definitely are. But we need to remember to test to make sure our filtering works when we click on a recipe's category. We've only entered one Category so far, so we can't test that yet. While we're in the view code, though, let's finish that stuff off.

Pages: 1, 2, 3, 4

Next Pagearrow