Friday, May 15, 2009

A View and a View

‹prev | My Chain | next›

The first view that I need to create renders the list of meals for a given year. We tend to have a lot of meals in a year, so this list is a simple unordered list.

In the view specification, before(:each) example, two meals suffice to create a list:
  before(:each) do
assigns[:meals] = @meal =
[
{
'title' => 'Meal 1',
'_id' => '2009-05-14'
},
{
'title' => 'Meal 2',
'_id' => '2009-05-14'
}
]
end
The two examples that describe the list are:
  it "should display a list of meals" do
render("/views/meal_by_year.haml")
response.should have_selector("ul li", :count => 2)
end

it "should link to meals" do
render("/views/meal_by_year.haml")
response.should have_selector("li a", :content => "Meal 1")
end
The Haml code that makes these examples pass is:
%ul
- @meal.each do |meal|
%li
%a{:href => "/meals/#{meal['_id']}"}= meal['title']
One view down...
(commit)

The other view that I need to create is a corresponding CouchDB view. I need to map each document to the year in which it was prepared, pointing to the meal ID and title (enough information to hyperlink to the meal). Additionally, a simple reduction pointing to the meal ID and title will allow me to group recipes by the year. The view that I want is:
{
"views": {
"by_year": {
"map": "function (doc) { emit(doc['date'].substring(0, 4), [doc['_id'], doc['title']]); }",
"reduce": "function(keys, values, rereduce) { return values; }"
}
},
"language": "javascript"
}
The date is an ISO 8601 string (YYYY first), which is the reason for the substring(0,4) call on it.

With that in place, and some non-trivial reworking of the views to match the actual data structure from the map-reduce rather than what I had guessed it would be, I can work my way back out to the Cucumber scenario to define how the next two steps behave—on the 2009 meals page, the 2009 recipe should be included, but not the 2008 recipe:
Then /^the "([^\"]*)" meal should be included in the list$/ do |title|
response.should have_selector("li a", :content => title)
end

Then /^the "([^\"]*)" meal should not be included in the list$/ do |title|
response.should_not have_selector("a", :content => title)
end
All that is left is to verify that clicking through to the 2008 meals works:



(commit)

Tomorrow.

No comments:

Post a Comment