La boutique : StoreController

Bon, ben voila, nous avons géré nos produits. Mais le but est de faire un super site de vente en ligne, aussi, nous ne pouvons pas laisser l'accessibilité à cette gestion, nous devons faire un autre controlleur qui sera charger d'afficher la boutique: StoreController.

Un coup de générateur : script/generate controller store index list show oubien passez par les menus de rails.vim : Plugin->Rails->Generate->Controller azvec comme paramètres store index list show.

Nous avons un nouveau controller tout neuf, mais qui ne comporte que 3 méthodes vides: index, list et show.

[ruby]
class StoreController<ApplicationController
  def list
  end

  def index
  end

  def show
  end

end

Bon,c'est pas tout ca, mais on a une boutique à faire.

Donc, commençons par récupérer les informations dont nous avons besoins, regardons le contenu de la méthode list, nous devons la copier pour lire les infos des produits:

[ruby]
  def list
    @product_pages, @products = paginate :products, :per_page => 10, :order => 'title'
  end

Hop Copier/Coller dans notre nouveau StoreController en lieu et place la méthode générée. Nous avons donc nos produits à disposition en mémoire. Notez au passage le paramètre :order que nous ajoutons pour trier nos produit sur le title de façon ascendante.

OK, maintenant, la vue : gamestore/app/view/layouts/store.rhtml : c'est le template du niveau controller, c'est a dire que toutes les actions effectuées dans ce controleur hériterons de la mise en forme de ce fichier. c'est le canevas pour nos méthodes index, list et show.

[html]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>GameStore</title>
  <%= stylesheet_link_tag 'scaffold','main','store' %>
</head>
<body>
	<div id="header">
		<h1>GameStore</h1>
	</div>
	<div id="main">
		<p style="color: green"><%= flash[:notice] %></p>				
			<%= yield  %>
	</div>
	<div class="clear"></div>
	<div id="footer">
		<p>Copyright &copy; 2008 - Boutique en ligne - démo - <a href="mailto:mcgivrer@gmail.com">Contact</a></p>
	</div>
</body>
</html>

Comme vous pouvez le constater, nous avons ajouté 2 feuilles de styles : main et store. la première défini la look globale et le zoning de notre boutique, tandis que la deuxième permettra de définir toute la mise en forme graphique des éléments de cette page, comme les titres, le description, les images, etc... vous pouvez les télécharger ci-dessous :

Pour plus d'explication, nous pouvons résumer main.css par la division de la page de la boutique en 3 zones principales : #Header, #Main et #Footer.

Mais il nous manque le template de rendu pour la méthode list. le voilà dans gamestore/app/views/store/list.rhtml:

[html]
<div id="content">
	<div class="product_list">
	<% for @product in @products %>
		<div class="product item">
		<% if @product.image %>
			<%= image_tag url_for_file_column("product","image","mini"), :class => "product" %>
		<% end %>
			<div class="infos">
				<h2><%= link_to @product.title, {:action => 'show', :id => @product.id}%></h2>
				<div class="price"><%= h fmt_currency(@product.price) %></div>
				<div class="description"><%= h @product.description%></div>
			</div>
			<div class="clear"></div>
		</div>
	<% end %>
	</div>
</div>

Relançons notre serveur Rails (WeBrick) et appelons http://localhost:3000/store/list :

La vue list du StoreController

Voila une belle liste de produit. Mais nous devons également définir les méthodes index et show:

[ruby]
def index
  redirect_to :action=>'list'
end

def show
@product = Product.find(params[:id])
end

Nous redirigeons la page index vers l'affichage de la liste, et la méthode show nécessite un nouveau template gamestore/app/view/store/show.rhtml :

[ruby]
<div id="content">
<div class="item">
	<% if @product.image %>
		<%= image_tag url_for_file_column("product","image","thumb") %>
	<% end %>
	<h2><%= h @product.title %></h2>
	<div class="description"><%= h @product.description%></div>
	<hr size="2" noshadow="noshadow" />
	<div class="price">
		<%= h @product.price %>€
	</div>
</div>
<div class="clear"></div>
<%= link_to "Continuer vers la boutique", {:controller => 'store', :action => 'list'} %>
</div>

Cliquez sur l'un des titres de produit, et vous devriez arriver sur la page du produit, par exemple http://localhost:3000/store/show/13 :

Page d'un produit

Toutes les actions de cette partie sont codées et opérationnelles.

Bon, et maintenant ?

Commençons par faire en sorte qu'il n'y ait plus besoin de spécifier un répertoire dans l'url pour pointer sur le bon controller. pour cela, allons faire un tour du côté du fichier config/routes.rb, et ajouter la ligne suivante :

[ruby]
map.connect '', :controller => "store"

Ensuite, aller dans le répertoire public, et renomer (ou supprimer, comme vous préférez) le fichier public/index.html en index.old.html. Ce fichier est en fait l'accueil par défaut de toutes les application générée avec Rails.

Voila, redémarez le serveur rails (Webrick) et ouvrez à nouveau votre navigateur sur l'url http://localhost:3000/. Maintenant, vous tombez directement sur votre liste de produit disponible dans votre boutique ;)

Dans le "prochain épisode" nous créerons une deuxième vue Produit avec un affichage plus compact, et nous rendrons notre site multilingue à l'aide du plugin "Globalize".

Vous pouvez télécharger l'application rails issue de ce tutorial à cette adresse :