2.2. Categories
2.1 script/generate
%: ruby script/generate model Document
%: ruby script/generate controller document
%: ruby script/generate model Category
%: ruby script/generate controller category
Yep there is also the Document model and controller, just to have them done.
Open the app/models/category.rb file. This is where the Document class is defined. Add the following two lines in the class :
has_and_belongs_to_many :documents
2.2 Model, Controller
# define the model
model :category
# find all the categories in the db and store them into the @items array
def list
@items = Category.find_all
end
# find the wanted item and store it into @item
def show
@item = Category.find(@params["id"])
end
# create a new Category object
def new
@category = Category.new
end
def create
item = Category.new # Create a new instance of Author, so create a new author
item.attributes = @params["category"] # The fields of item should be set
# to what's in the "new_item" hash
if item.save # Try to save our item into the database
redirect_to(:action => "list") # Return to the list page if it suceeds
else
render_text "Couldn't add new item" # Print an error message otherwise
end
end
protected
def secure?
["new", "create", "edit" ].include?(action_name) # define the secured methods
end
Here we have defined the four most important methods : list, show, new and create. The last one are used to create new categories. We have to create the views for the first three ones. Why not the last ? Because it redirects to other pages.
2.3 Views
<h1>Categories</h1>
<p><%= link_to("Add", :controller => "category", :action => "new") %> one category.</p>
<ul>
<% @items.each do |@item| %>
<h2><%= link_to(@item.name, :controller => "category", :action => "show", :id => @item.id) %></h2>
<ul>
<% for document in @item.documents %>
<li>
<%= link_to(document.title, :controller => "document", :action => "show", :id=> document.id) %>
</li>
<% end %>
</ul>
<br />
<% end %>
</ul>
How does it work ? Simple. The list method into the category controller create the @items array and in the list view @items is accessible. Because in @items there is all the categories we just have to take each item inside (each category) and use it as we want. Here we just display some attributes of each category : the name, and then we display the list of each documents who belongs to this category. You can see here how simple it is to access to all the category’s documents.
In show.rhtml paste the following code :
<h1><%= @item.name %></h1>
<p>
<%= @item.description %>
</p>
<ul>
<% for document in @item.documents%>
<li>
<%= link_to(document.title, :controller => "document", :action => "show", :id => document.id) %>
</li>
<% end %>
</ul>
This one is quite simple too. The show method of the controller simply get the item we have specified via the id in the url and pass it to the view as @item. Then we use it as we did in the list view. We display the name, and the description of the category. At last we display the list of the documents which are inside the category.
Now the difficult part (joking) : open the new.rhtml file. Paste the following code inside :
<h1>New Category</h1>
<%= error_messages_for 'category' %>
<%= form 'category', :action => 'create' %>
<%= link_to 'Back', :action => 'list' %>
Here we define a form. RoR generate it using the table, the action attribute of the form will be create. So now you understand why we have a create controller and no create view. When the user will click on the Create button parameters will be passed to the create method and then processed.
2.4 Let's test !
Open your browser and go to http://howto/category/list. You should see a quite simple page with a title : Categories and a line with a link : Add one category.. Click on the link. If you are not logged in you are redirected to the login page. Log in. You should be redirected to the add a category page. Add a category. When done you are redirected to the list page. You should see your new category, click on the link and you go to the show page. You can there see the description of your category. There is no documents in it.
Play around with these functions, add one or two categories.