Une première application ?

Oui, bon, est-ce bien nécessaire de refaire l'éternel "Hello World" ? Et bien dans le cas de Rails, dans tous les cas, on y coupe pas, et en plus ça se fait tout seul. Il suffit de lancer un simple : rails gamestore dans votre console. Mais si vous êtes sous Cream (le VIM amélioré), allez dans le menu Plugin->Rails->Projects->News.

mon application

et par la magie des scripts railesques, on se retrouve avec un répertoire plein de trucs, on fait un petit script/server et dans votre navigateur préféré (firefox biensur ;) ) faites un petit http://localhost:3000/ et vous vous retrouverez avec un magnifique :

Firefox

Je vous fais grâce d'une description du répertoire type d'une application rails, je vous laisse vous reporter à la litterature que vous trouverez sur le web pour cela. Mais il nous manque une truc essentiel : une base de données !

Donc, comme vous avez déjà un serveur MySQL (comment ça vous en avez pas un ?), créez une petite base avec comme doux nom gamestore_development.

mysqladmin -u root -p create gamestore_development

Connectons notre application Rails à cette base de données en éditant le fichier de configuration de la base (config/database.yml) et modifiez les ligne suivante pour ajuster votre compte/mot de passe et le serveur+port de mysql :

development:
 adapter: mysql
 database: gamestore_development
 username: root
 password: xxxxxxx
 host: localhost
 port: 3306

Une fois cela fait, on passe aux choses sérieuses.

Et ensuite, créons une petite table répondant au doux nom de products (attention, le 's' à la fin n'est pas là pour la déco), comportant les champs suivants :

  • id BIGINT
  • title VARCHAR(255)
  • description TEXT
  • image VARCHAR(255)
  • price
  • date_available DATETIME

Pour cela, nous allons utiliser une des particularité de Ruby et de Rails le script/generate model Product

après génération, vous avez toutes une série de fichiers créé, dont deux nous interressent tout particulièrement :

  • app/model/product.rb
  • @@db/migration/001_create_products.rb

Editons ce deuxième fichier :

[ruby]
class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.column "title",           :string,	:limit => 100, :default => "title",:null => false
      t.column "description",     :text
      t.column "image",           :string,	:default => "/images/cover.jpg",:null => false
      t.column "price",           :float,		:default => -1.0, :null => false
      t.column "date_available",  :datetime,	:null => false
    end
  end

  def self.down
    drop_table :products
  end
end

Ainsi, par ce script, et en executant un plugin->rake->migrate après l'avoir sauvé, biensur, vous aurez une belle table products dans votre base de données toute neuve.

Une fois tout celà ficelé, retournez dans votre console dans gedit vous faite un petit script/generate scaffold Product store, oubien dans le menu Plugin->Rails->Generate->Scaffold, en précisant dans la fenêtre qui s'ouvre "Product product" et après quelques secondes relancez votre navigateur avec l'adresse @@http://localhost:3000/product/.

Et magie de Rails, grâce au prophète Ruby vous obtenez une superbe fenêtre au look (moche) qui vous permet de faire toutes les opérations du CRUD (non, ce n'est pas un mouvement terroriste...) sur votre liste de produit.

Commençons par en ajouter un, de produit, en utilisant le petit lien "New Product" sur la page affichée. Vous obtenez la page ci-dessous :

Firefox

L'image à télécharger : file_column

Dans notre modèle de porduit, nous avons un champs judicieusement nommé image. Nous allons lui demander de mémoriser un chemin relatif vers une image que nous uploaderons sur le site. Pour cela, nous utiliserons le plugin file_column qui va intégrer toute la mécanique d'upload et de stockage d'image.

La commande suivante installera ce plugin :

 script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk

Dans notre modèle gamestore/app/models/product.rb ajoutons en haut la ligne :

[ruby]
class Product < ActiveRecord::Base
  file_column :image, 
    :magick => { :geometry=>"400x600", 
      :versions=>{ :thumb=> "138x188", :mini=> "60x90" } }
end

Par cette "simple" ligne, nous expliquons à rails qu'il doit passer par la mécanique du plugin pour gérer ce champ et l'image qui va avec: magique, non ? Pour plus d'ionformation sur le charabiat qui suit le paramètre :magick, reportez vous à l'article concernant RMagick sur mon blog.

Nous allons maintenant enrichir notre interface d'édition de produit.

Pour commencer, éditez le fichier gamestore/app/view/product/new.rhtml et remplacez la ligne

 <% form_tag :action=> 'create' do %>

par :

 <% form_tag( { :action=> 'create' }, :multipart=> true ) do %>

Editez ensuite le fichier app/gamestore/views/product/_form.html:

remplacez les lignes

[ruby]
<p><label for="product_image">Image</label><br/>
<%= text_field 'product', 'image'  %></p>

par ces lignes :

[ruby]
<p><label for="product_image">Image</label>
<%= file_column_field 'product', 'image'  %></p>
<%if @product.image %>
  <p><%= image_tag url_for_file_column("product", "image") %></p>
<%end%>

Et maintenant, appeler l'url : http://localhost:3000/product/new

Vous pourrez ajouter votre premier produit avec image :) .

Sinon, nous devons légèrement retoucher l'affichage de la liste de produit. Aussi, éditons le fichier gamestore/app/views/product/list.rhtml:

remplacer les lignes auto-générées :

[ruby]
<table>
  <tr>
  <% for column in Product.content_columns %>
    <th><%= column.human_name %></th>
  <% end %>
  </tr>
<% for product in @products %>
  <tr>
  <% for column in Product.content_columns %>
    <td><%=h product.send(column.name) %></td>
  <% end %>
    <td><%= link_to 'Show', :action => 'show', :id => product %></td>
    <td><%= link_to 'Edit', :action => 'edit', :id => product %></td>
    <td><%= link_to 'Destroy', { :action => 'destroy', :id => product }, :confirm => 'Are you sure?', :method => :post %></td>
  </tr>
<% end %>
</table>

par ces lignes :

[ruby]
<% for @product in @products %>
<tr valign="top" class="ListLine <%= cycle('odd','even') %>">
	<td>		  
		<%= image_tag url_for_file_column("product","image","mini")%>
	</td>
	<td width="60%">
	  <span class="ListTitle"><%= h(@product.title) %></span><br />
	  <%= h(truncate(@product.description, 200)) %>
	</td>
	<td align="right">
	  <%= @product.date_available.strftime("%y-%m-%d") %><br/>
	  <strong><%= fmt_currency(@product.price) %></strong>
	</td>
	<td class="ListActions">
		<%= link_to 'Show', :action => 'show', :id => @product %><br/>
		<%= link_to 'Edit', :action => 'edit', :id => @product %><br/>
		<%= link_to 'Destroy', { :action => 'destroy', :id => @product }, :confirm => "Are you sure?" %>
    </td>
  </tr>
<% end %>

Et donc, en reprenant l'url http://localhost:3000/product/list. et voila ce que vous obtenez :

La liste des produits

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