Now I want to create a new page that lists all the species in the birds table. That is, it looks like this:
Brooklyn Bird Report Master Bird List
- Fulvous Whistling-Duck Dendrocygna bicolor
- Greater White-fronted Goose Anser albifrons
- Snow Goose Chen caerulescens
- Ross’s Goose Chen rossii
- Brant Branta bernicla
…
This will live in the file /masterbirdlist.rhtml
How to do it? I begin by creating a regular HTML file named masterbirdlist.rhtml and putting it in the app/views/bbr directory, but that doesn’t work. It just tells me “Unknown action No action responded to masterbirdlist.rhtml.” OK. Looking back at the notes from Day 1, I see how to handle that. I add this method to the bbr_controller.rb
file:
def masterbirdlist
render_text "Hello"
end
Now I get “Hello” for the masterbirdlist. Of course that’s not what I want. I want to load the masterbirdlist.rhtml file. How do I do that? About this point I begin wondering what the manual says. Googling for it, it appears that there isn’t one. That compares very unfavorably with PHP and Java, both of which at least have documentation, not to mention reams of third party books available. (Later I found this site, but it doesn’t appear to be a true comprehensive manual; just a random collection of HowTos.) However, there does seem to be some API documentation which mentions render_file()
methods. Maybe that’s what I need? No wait. I remember this now. I bet I have to generate a controller for the masterbirdlist:
~/Web sites/bbr$ script/generate controller masterbirdlist
exists app/controllers/
exists app/helpers/
exists app/views/masterbirdlist
exists test/functional/
identical app/controllers/masterbirdlist_controller.rb
identical test/functional/masterbirdlist_controller_test.rb
identical app/helpers/masterbirdlist_helper.rb
That seems to work. I thought this was just for mapping to database tables, but apparently it’s for all pages. This gives me the “Unknown action No action responded to index” at /masterbirdlist. But I’ll create a view for this in app/views/masterbirdlist/index.rhtml. Bingo! That works.
Now let’s add the code to generate the list of species:
<ul>
<% @birds.each do |bird| %>
<li><%= bird.common_name %></li>
<% end %>
</ul>
This produces
NoMethodError in
Masterbirdlist#index
Showing app/views/masterbirdlist/index.rhtml where line #14 raised:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.each
So now I have to create the birds
variable. Thus I add this code to the masterbirdlist_controller.rb
:
def index
@birds = Bird.find_all
end
Now I get this error:
NameError in
Masterbirdlist#index
uninitialized constant Bird
I suspect this is because I haven’t mapped that table in Rails yet. i.e. I haven’t generated a model for the birds. Let’s do that:
$ script/generate model Bird
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/bird.rb
create test/unit/bird_test.rb
create test/fixtures/birds.yml
And now the page works. OK. I ‘m starting to get the hang of this. Adding the genus to the list is easy:
<% @birds.each do |bird| %>
<li><%= bird.common_name %> <i><%= bird.genus %></i></li>
<% end %>
Now let’s add the species:
<% @birds.each do |bird| %>
<li><%= bird.common_name %> <i><%= bird.genus bird.species %></i></li>
<% end %>
Oops. That didn’t work:
ArgumentError in
Masterbirdlist#index
Showing app/views/masterbirdlist/index.rhtml where line #15 raised:
wrong number of arguments (1 for 0)
Hmm. Do I just need to put that in two separate tags or do I need to learn how to concatenate strings or terminate statements in Ruby? Concatenating seems to work; and it uses the plus sign, same as in Java:
<% @birds.each do |bird| %>
<li><%= bird.common_name %> <i><%= bird.genus + bird.species %></i></li>
<% end %>
However, it turns out I forgot a space, so I might as well just go ahead and use two tags anyway:
<% @birds.each do |bird| %>
<li><%= bird.common_name %> <i><%= bird.genus %> <= bird.species %></i></li>
<% end %>
I think that’s as far as I’m going to go tonight, but just maybe I am speeding up a little past what I could do with PHP (though I still don’t fully grok how the site is getting organized, and the URLs mapped.)