In this second part of a two-part series, we'll finish creating reports that can be accessed via the Internet. This article is excerpted from chapter 5 of the book Practical Reporting with Ruby and Rails, written by David Berube (Apress; ISBN: 1590599330).
Building Reports Accessible from the Internet (Page 1 of 5 )
Creating the Controller for the Web Report
The controller will respond to actions of the user by taking data from the model and presenting it via your views. The controller is named home, since you will have just one page. Create the app/controllers/home_controller.rb file with the code shown in Listing 5-6.
Listing 5-6.Home Controller for the Web Report (app/controllers/home_controller.rb)
class HomeController < ApplicationController def index @actors_today = [] @actors_tomorrow = [] Actor.find(:all).each do |actor| @actors_today << {:actor=>actor, :bookings => actor.bookings.find(:all, :conditions => [ 'TO_DAYS(booked_at)=' << 'TO_DAYS(NOW())'])} @actors_tomorrow << {:actor=>actor, :bookings => actor.bookings.find(:all, :conditions => [ 'TO_DAYS(booked_at)=' << 'TO_DAYS(NOW())+1'])} end end end
This controller has just one action: index, which displays the bookings for today and tomorrow.
Creating the View for the Web Report
Next, let's create a view that actually displays this data, as shown in Listing 5-7.
Listing 5-7.The Single View for the Actor Scheduling Application (app/views/home/ index.rhtml)
<style> body { font-family: sans-serif } h2 { margin-left: 10pt;} p { margin-left: 10pt; } </style>
<h1>Today's Schedule:</h1>
<% @actors_today.each do |actor_today| %> <h2><%= actor_today[:actor].name %></h2> <p><%if actor_today[:bookings].length > 0 %> actor_today[:bookings].each do |b| <%=b.booked_at.strftime('%I:%m%p') %> <%=b.room.name %>, <%=b.project.name %><br> <%end%> <%else%> Nothing for today! <%end%> </p>
<% end %>
<h1>Tomorrow's Schedule:</h1>
<% @actors_tomorrow.each do |actor_tomorrow| %> <h2><%= actor_tomorrow[:actor].name %></h2> <p><%if actor_tomorrow[:bookings].length > 0 %> actor_tomorrow [:bookings].each do |b| <%=b.booked_at.strftime('%I:%m%p') %>, <%=b.room.name %>, <%=b.project.name %<br> <%end%> <%else%> Nothing for tomorrow! <%end%>
<% end %>
Save this file as app/views/home/index.rhtml.
Now you need just one more piece: a layout, which is used as a template. In other words, the view is displayed inside the layout. Listing 5-8 shows the layout.
Listing 5-8.Layout for the Actor Schedule View (app/views/layouts/application.rhtml)
Save this as app/views/layouts/application.rhtml. This layout will be used automatically for all pages in the application by default. You can set up a layout for just one controller, and you can also manually override layouts for a given action.