<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>OnTheRailsAgain</title><link>http://ontherailsagain.com</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/OnTheRailsAgain" /><language>fr-FR</language><lastBuildDate>Sun, 13 May 2012 17:00:00 PDT</lastBuildDate><feedburner:info uri="ontherailsagain" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><description></description><item><title>Single Table Inheritance</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/-h2ZGnewHt4/single-table-inheritance</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nima</dc:creator><pubDate>Sun, 13 May 2012 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/single-table-inheritance</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>comment organiser les modèles ;</li>
    <li>comment créer la table ;</li>
    <li>comment gérer le type du modèle avec un seul contrôleur.</li>
  </ul>
</div>
<h2 id='qu-est-ce-que-c-est-1'>Qu'est-ce que c'est ?</h2>
<p>
  «Single Table Inheritence» (STI) (en français «Héritage de table unique») est un moyen de faire de l'héritage en n'utilisant qu'une seule table en base de données. Le tout est de savoir comment structurer ses modèles et le tour est joué !
</p>
<h2 id='illustration-par-un-exemple-2'>Illustration par un exemple</h2>
<p>
  Supposons que nous avons plusieurs types d'utilisateurs. Des administrateurs qui ont tous les droits et des éditeurs qui n'ont que des droits d'édition. Nous pouvons donc ici utiliser l'héritage pour nos modèles utilisateurs. Une classe mère <code>User</code> et deux classes filles <code>Administrator</code> et <code>Editor</code>.
</p>
<h3 id='creation-des-modeles-3'>Création des modèles</h3>
<p>
  Comme tout héritage classique, il faut une classe par modèle.
</p>
<pre class='prettyprint linenums'># app/models/user.rb
class User &lt; ActiveRecord::Base
end</pre>
<pre class='prettyprint linenums'># app/models/editor.rb
class Editor &lt; User
end</pre>
<pre class='prettyprint linenums'># app/models/administrator.rb
class Administrator &lt; User
end</pre>
<p class='alert alert-info'>
  Pour avoir une structure plus «propre», on peut mettre les fichiers <code>editor.rb</code> et <code>administrator.rb</code> dans un sous dossier <code>/app/models/users/</code> et il faudrait alors suffixer les noms de classe des deux modèles par <code>Users::</code>.
</p>
<h3 id='creation-de-la-table-4'>Création de la table</h3>
<p>
  Comme je l'ai dit plus haut, une seule table en base de données est nécessaire. Cette table doit contenir les champs des trois modèles. Tout ce qui correspond au modèle <code>User</code>, <code>Editor</code> et <code>Administrator</code>.
</p>
<p>
  En plus de tous ces champs, il faut rajouter une colonne <code>type</code> qui permettra de savoir de quel type est la ressource en question.
</p>
<pre class='prettyprint linenums'># db/migrate/124812048_create_user.rb
class CreateUser &lt; ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :username
      t.string :password
      ...
      t.string :type
      t.timestamps
    end
  end
  def self.down
    drop_table :users
  end
end</pre>
<img alt="Du modèle d'héritage Ruby aux tables en bases de données" src='http://ontherailsagain.com/article_images/Single_Table_Inheritance/Single_Table_Inheritance.png' title='Du Ruby à la BDD' />
<h3 id='ajout-des-routes-5'>Ajout des routes</h3>
<p>Pour ce qui est des routes, il suffit de les déclarer comme des ressources. Si vous voulez n'utiliser qu'un seul contrôleur vous pouvez faire comme ceci&nbsp;:</p>
<pre class='prettyprint linenums'># config/routes.rb
resources :users,          :controller =&gt; 'user', :type =&gt; User.name
resources :editors,        :controller =&gt; 'user', :type =&gt; Editor.name
resources :administrators, :controller =&gt; 'user', :type =&gt; Administrator.name</pre>
<p>
  En rajoutant un couple clé/valeur après la définition de la ressource, on précise au routeur de passer un paramètre qui correspond à la clé avec sa valeur associée. Ici, on définit le paramètre <code>:type</code> avec le nom de la ressource.
</p>
<p>
  De cette façon quand vous accèderez à l'url <code>/editors/new</code> la requête sera redirigé vers le contrôleur <code>UsersController</code>.
</p>
<h3 id='cote-controleur-6'>Côté contrôleur</h3>
<p>
  Voyons maintenant comment différencier les trois types d'utilisateurs côté contrôleur.
</p>
<p>
  Le <a href='http://stackoverflow.com/questions/5246767/sti-one-controller/5254995#5254995' title="Réponse d'Alan Peabody sur StackOverflow">post d'Alan Peabody</a> sur Stack Overflow propose une solution intéressante pour gérer le type de modèle dans le contrôleur. Il suggère d'ajouter une méthode privée qui permettra d'accéder à la classe du type de modèle concerné.
</p>
<pre class='prettyprint linenums'># app/controllers/users_controller.rb
private
def user_type
  params[:type].constantize
end</pre>
<p>
  Ainsi vous n'aurez pas à vous soucier de la gestion du type dans vos autres méthodes.
</p>
<pre class='prettyprint linenums'># app/controllers/users_controller.rb
def index
  @users = user_type.all
  # …
end
def new
  @user = user_type.new
  # …
end
def create
  @user = user_type.new(params)
  # …
end</pre>
<p>
  N'hésitez pas à proposer d'autres solutions ou à me reprendre si besoin !
</p>
<h2 id='references-7'>Références</h2>
<ul>
  <li>
    <a href='http://juixe.com/techknow/index.php/2006/06/03/rails-single-table-inheritance/' target='_blank'>Rails Single Table Inheritance</a>
    de TechKnow.
  </li>
  <li>
    <a href='http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html' target='_blank'>Single Table Inheritance in Rails</a>
    de Alex Reisner
  </li>
  <li>
    <a href='http://martinfowler.com/eaaCatalog/singleTableInheritance.html' target='_blank'>Single Table Inheritance</a>
    de Martin Fowler
  </li>
  <li>
    <a href='http://stackoverflow.com/questions/5246767/sti-one-controller/5252136#5252136' target='_blank'>Réponse de fl00r</a>
    – Stack Overflow
  </li>
  <li>
    <a href='http://stackoverflow.com/questions/5246767/sti-one-controller/5254995#5254995' target='_blank'>Réponse d'Alan Peabody</a>
    – Stack Overflow
  </li>
</ul>
]]></content:encoded><description>«Single Table Inheritence» (STI) (en français «Héritage de table unique») est un moyen de faire de l'héritage en n'utilisant qu'une seule table en base de données. Le tout est de savoir comment structurer ses modèles et le tour est joué !</description><feedburner:origLink>http://ontherailsagain.com/articles/single-table-inheritance</feedburner:origLink></item><item><title>Ressources imbriquées</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/UhgaQW4K9eE/ressources-imbriquees</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nicolas</dc:creator><pubDate>Thu, 10 May 2012 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/ressources-imbriquees</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='require'>
  Pré-requis :
  <ul>
    <li>
      Avoir compris le
      <a href='http://ontherailsagain.com/articles/comprendre-les-routes-en-rails' target='_blank'>fonctionnement des routes</a>.</a>
    </li>
    <li>
      Avoir vu le
      <a href='http://ontherailsagain.com/articles/le-routage-de-ressources-en-rails' target='_blank'>routage de ressources</a>.</a>
    </li>
  </ul>
</div>
<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>Déclarer les ressources imbriquées au niveau des routes.</li>
    <li>Adapter les contrôleurs et les vues pour gérer ces ressources imbriquées.</li>
  </ul>
</div>
<p>Nous avons vu comment définir des relations d'associations entre différents modèles, ainsi que la façon de définir des routes pour des ressources. Passons maintenant à la gestion des ressources imbriquées.</p>
<h2 id='presentation-du-probleme-1'>Présentation du problème</h2>
<p>Reprenons l'exemple de l'article sur les <a href="http://ontherailsagain.com/articles/les-associations-many-to-many" target="_blank">associations many-to-many</a> pour illustrer le problème. Nous avons un modèle <code>Article</code> et un modèle <code>Tag</code>. Un article peut avoir plusieurs tags et un tag appartient à plusieurs articles. Ces modèles sont les ressources que nous allons manipuler et sont donc liés par une relation many-to-many.</p>
<p>Le problème est que nous voulons représenter cette relation dans les URLs, c'est-à-dire par exemple, accéder à la liste de tous les tags d'un article par l'url : <em>http://monsite.fr/articles/id_de_l_article/tags.</em></p>
<h2 id='routes-2'>Routes</h2>
<p>Afin de représenter cette imbrication de ressources au niveau des URLs, on définit les routes comme ceci :</p>
<pre class='prettyprint linenums'># config/routes.rb
resources :articles do
  resources :tags
end</pre>
<p>Cette déclaration permet de définir les routes pour les <code>Articles</code> mais aussi pour les <code>Tags</code>.</p>
<h3 id='crud-methodes-http-et-actions-3'>CRUD, méthodes HTTP et actions</h3>
<p>Voyons de plus près l'ensemble des routes générées :</p>
<table>
  <thead>
    <tr>
      <th>Méthode <br />HTTP</th>
      <th>URL</th>
      <th>Action</th>
      <th>Utilité</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles</span></td>
      <td>index</td>
      <td>Afficher la liste de tous les articles</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/new</span></td>
      <td>new</td>
      <td>Afficher un formulaire pour créer un article</td>
    </tr>
    <tr>
      <td>POST</td>
      <td><span class="code">/articles</span></td>
      <td>create</td>
      <td>Créer un nouvel article</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:id</span></td>
      <td>show</td>
      <td>Afficher un article</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:id/edit</span></td>
      <td>edit</td>
      <td>Afficher un formulaire pour éditer un article</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td><span class="code">/articles/:id</span></td>
      <td>update</td>
      <td>Mettre à jour un article</td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td><span class="code">/articles/:id</span></td>
      <td>destroy</td>
      <td>Supprimer un article</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:article_id/tags</span></td>
      <td>index</td>
      <td>Afficher la liste de tous les tags d'un article</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:article_id/tags/new</span></td>
      <td>new</td>
      <td>Afficher un formulaire pour créer un tag appartenant à un article</td>
    </tr>
    <tr>
      <td>POST</td>
      <td><span class="code">/articles/:article_id/tags</span></td>
      <td>create</td>
      <td>Créer un nouveau tag pour un article</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:article_id/tags/:id</span></td>
      <td>show</td>
      <td>Afficher un tag spécifique appartenant à un article</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:article_id/tags/:id/edit</span></td>
      <td>edit</td>
      <td>Afficher un formulaire pour editer un tag appartenant à un article</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td><span class="code">/articles/:article_id/tags/:id</span></td>
      <td>update</td>
      <td>Mettre à jour un tag appartenant à un article</td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td><span class="code">/articles/:article_id/tags/:id</span></td>
      <td>destroy</td>
      <td>Supprimer un tag appartenant à un article</td>
    </tr>
  </tbody>
</table>
<p>Il est important de noter que les URLs permettant d'accéder aux tags requièrent l'<code>id</code> d'un article, en effet, nous allons devoir fournir cet <code>id</code> à chaque path helper. Voyons justement les chemins et URLs qui sont générés à partir de cette déclaration de route.</p>
<h3 id='chemins-et-urls-generes-4'>Chemins et URLs générés</h3>
<table>
  <thead>
    <tr>
      <th>Path helper</th>
      <th style='padding-left: 10px; padding-right: 10px;'>Méthode <br />HTTP</th>
      <th style='padding-left: 10px; padding-right: 10px;'>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan='2'><span class="code">articles_path</span></td>
      <td>GET</td>
      <td>index</td>
    </tr>
    <tr>
      <td>POST</td>
      <td>create</td>
    </tr>
    <tr>
      <td rowspan='3'><span class="code">article_path(:id)</span> Ce path prend en paramètre l'id de l'article à afficher, modifier ou supprimer</td>
      <td>GET</td>
      <td>show</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td>update</td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td>destroy</td>
    </tr>
    <tr>
      <td><span class="code">new_article_path</span></td>
      <td>GET</td>
      <td>new</td>
    </tr>
    <tr>
      <td><span class="code">edit_article_path(:id)</span> Ce path prend en paramètre l'id de l'article à modifier</td>
      <td>GET</td>
      <td>edit</td>
    </tr>
    <tr>
      <td rowspan='2'><span class="code">article_tags_path</span></td>
      <td>GET</td>
      <td>index</td>
    </tr>
    <tr>
      <td>POST</td>
      <td>create</td>
    </tr>
    <tr>
      <td rowspan='3'><span class="code">article_tag_path(:article_id, :tag_id)</span> Ce path prend en paramètre l'id de l'article auquel appartient le tag à modifier ainsi que l'id de ce dernier</td>
      <td>GET</td>
      <td>show</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td>update</td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td>destroy</td>
    </tr>
    <tr>
      <td><span class="code">new_article_tag_path</span></td>
      <td>GET</td>
      <td>new</td>
    </tr>
    <tr>
      <td><span class="code">edit_article_tag_path(:article_id, :tag_id)</span> Ce path prend en paramètre l'id de l'article auquel appartient le tag à modifier ainsi que l'id de ce dernier</td>
      <td>GET</td>
      <td>edit</td>
    </tr>
  </tbody>
</table>
<h2 id='controleur-5'>Contrôleur</h2>
<p>Après avoir modifié les routes, il est souvent nécessaire d'apporter des modifications au code existant pour pouvoir faire fonctionner l'application avec les ressources imbriquées. Par exemple, si vous avez générés vos modèles à l'aide de scaffold et que l'ensemble des vues et contrôleurs existent déjà il faut les modifier.</p>
<h3 id='ajout-d-une-reference-6'>Ajout d'une référence</h3>
<p>Tout d'abord, nos tags sont dépendants d'un article, il faut donc définir cet article dans le contrôleur. Il est possible pour cela de créer une variable faisant référence à l'article auquel appartient le tag en ajoutant ce morceau de code au début de chaque méthode où la référence est nécessaire :</p>
<pre class='prettyprint linenums'>@article = Article.find(params[:article_id])</pre>
<p>Le <code>params[:article_id]</code> permet de récupérer l'id de l'article qui est passé dans l'URL.</p>
<p>Pour éviter la duplication de cette ligne de code, on peut créer une méthode qui définie cette variable. Pour que cette méthode soit exécutée avant les autres, on définit un <code>before_filter</code>, comme ceci&nbsp;:</p>
<pre class='prettyprint linenums'># app/controllers/tags_controller.rb
class TagsController &lt; ApplicationController
  before_filter :find_article  
  def index
    ...
  end
  ...
  def destroy
    ...
  end
  private
  def find_article
    @article = Article.find(params[:article_id])
  end
end</pre>
<p class='alert alert-info'>Pour en savoir plus sur les <a href="http://guides.rubyonrails.org/action_controller_overview.html#filters" target="_blank">filtres en Ruby On Rails</a></p>
<h3 id='modification-des-path-helpers-7'>Modification des path helpers</h3>
<p>Maintenant que la référence à l'article auquel appartient le tag est définie, il faut modifier les redirect_to dans les méthodes <code>create</code>, <code>update</code> et <code>destroy</code> comme ceci :</p>
<pre class='prettyprint linenums'># app/controllers/tags_controller.rb
class TagsController &lt; ApplicationController      
  …
  def create
    …
    format.html { redirect_to [@article, @tag] }
    …
  end
  def update
    …
    format.html { redirect_to [@article, @tag] }
    …
  end
  def destroy
    …
    format.html { redirect_to article_tags_url }
    …
  end
end</pre>
<p class='alert alert-info'>Il faut noter qu'en Ruby On Rails <code>[@article, @tag]</code> est équivalent à <code>article_tag_path(@article, @tag)</code></p>
<h2 id='vues-8'>Vues</h2>
<p>Ensuite il est nécessaire d'adapter l'ensemble des vues précédemment générées avec les scaffolds pour que ça fonctionne. Il faut modifier l'ensemble des paths existant en rajoutant les variables @article et @tag comme par exemple pour la vue index de tags :</p>
<pre class='prettyprint linenums'>&lt;h1&gt;Listing tags&lt;/h1&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Article&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
  &lt;/tr&gt;
&lt;% @tags.each do |tag| %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%= tag.name %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= tag.article_id %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Show', article_tag_path(@article, tag) %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Edit', edit_article_tag_path(@article, tag) %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Destroy', article_tag_path(@article, tag), :confirm =&gt; 'Are you sure?', :method =&gt; :delete %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;%= link_to 'New Tag', new_article_tag_path %&gt;</pre>
<p class='alert'>
  Évitez d'imbriquer trop de ressources. Essayez de vous limiter à une imbrication, cela permet d'avoir des URLs plus lisibles et des path helper moins long et moins contraignant à écrire.
</p>
<p>
  Par exemple si vous avez trois ressources Post, Comment et Favorite, vous pouvez diviser l'imbrication :
  <br /> <code>posts/:post_id/comments/:comment_id/favorites</code>
  <br /> en deux imbrications :
  <br /> <code>posts/:post_id/comments/:comment_id</code>
  <br /> <code>comments/:comment_id/favorites/:favorite_id</code>
</p>
<p>Pour cela il faut écrire les routes en deux parties comme ceci :</p>
<pre class='prettyprint linenums'># config/routes.rb
resources :posts do
  resources :comments
end
resources :comments do
  resources :favorites
end</pre>
<h2 id='ressources-9'>Ressources</h2>
<ul>
  <li><a href="http://guides.rubyonrails.org/routing.html#nested-resources" target="_blank">Guides Rails - Routes</a></li>
  <li><a href="http://rails-bestpractices.com/posts/11-needless-deep-nesting" target="_blank">Rails Best Practices - Needless deep nesting</a></li>
  <li><a href="http://guides.rubyonrails.org/action_controller_overview.html#filters" target="_blank">Filtres en Ruby On Rails</a></li>
</ul>
]]></content:encoded><description>Il arrive souvent d'avoir des ressources qui appartiennent à d'autres ressources. Dans ce genre de cas, il peut être intéressant de définir une imbrication de ressources au niveau des routes pour avoir des URLs cohérentes. Cet article présente comment définir ces routes ainsi que les modifications nécessaires à apporter au code des contrôleurs et des vues déjà existants.</description><feedburner:origLink>http://ontherailsagain.com/articles/ressources-imbriquees</feedburner:origLink></item><item><title>Associations polymorphiques</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/cle5fpH1o0w/associations-polymorphiques</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nima</dc:creator><pubDate>Sat, 28 Apr 2012 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/associations-polymorphiques</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='require'>
  Pré-requis :
  <ul>
    <li>connaître l'héritage ;</li>
    <li>
      avoir déjà vu les différentes associations
      (<a target="_blank" href="http://ontherailsagain.com/articles/les-associations-one-to-many" rel="nofollow">One-to-Many</a>,
      <a target="_blank" href="http://ontherailsagain.com/articles/les-associations-many-to-many" rel="nofollow">Many-to-Many</a>,
      <a target="_blank" href="http://ontherailsagain.com/articles/les-associations-many-to-many-avancees" rel="nofollow">Many-to-Many avancées</a>).
    </li>
  </ul>
</div>
<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>créer une association polymorphique ;</li>
    <li>utiliser une association polymorphique comme ressource imbriquée ;</li>
    <li>créer une ressource polymorphique de façon générique.</li>
  </ul>
</div>
<h2 id='qu-est-ce-que-c-est-1'>Qu'est-ce que c'est ?</h2>
<p>
  L'association polymorphique est une association qui permet à un modèle d'appartenir à plusieurs autres modèles. Il ne dépend donc pas d'un unique modèle. Par exemple, un modèle <span class="code">Comment</span> peut appartenir à des <span class="code">Articles</span>, mais aussi à des <span class="code">Events</span>. De cette façon, vous n'avez pas besoin de dupliquer des modèles ayant des informations similaires.
</p>
<h2 id='un-exemple-concret-2'>Un exemple concret</h2>
<p>
  Illustrons le problème par un exemple.
  Supposons que nous avons trois modèles : <span class="code">Article</span>, <span class="code">Event</span> et <span class="code">Photo</span>. Le but est de créer un unique modèle <span class="code">Comment</span> pour nos trois types de ressources.
</p>
<p>Voilà un schéma représentatif de ce que l'on veut obtenir&nbsp;:</p>
<img alt='Représentation schématique de la relation polymorphique' src='http://ontherailsagain.com/article_images/Associations_polymorphiques/Associations_polymorphiques.png' title="Schéma de l'association polymorphique" />
<h3 id='creation-du-modele-3'>Création du modèle</h3>
<p>
  Comme toujours, des conventions sont à respecter pour que tout se passe comme prévu. Le modèle <span class="code">Comment</span> n'étant plus lié à un modèle spécifique, il faut lui spécifier un champ qui réfèrera à l'ID de la ressource auquel il appartient ainsi que le type de ce dernier. Voilà comment générer le modèle <span class="code">Comment</span>&nbsp;
</p>
<pre class='prettyprint linenums'>$ rails g model Comment content:text commentable_id:integer commentable_type:string</pre>
<h3 id='migration-4'>Migration</h3>
<p>
  Pour récapituler, il faut stoquer l'ID de l'objet auquel le commentaire appartient et le type de ce dernier.
  Côté migration, deux façons d'écrire :
</p>
<pre class='prettyprint linenums'># db/migrate/201101249412_create_comments.rb
class CreateComments &lt; ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :content
      t.integer :commentable_id
      t.string  :commentable_type
      t.timestamps
    end
  end
end</pre>
<p>
  Ou :
</p>
<pre class='prettyprint linenums'># db/migrate/201101249412_create_comments.rb
class CreateComments &lt; ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :content
      t.integer :commentable, :polymorphic =&gt; true
      t.timestamps
    end
  end
end</pre>
<h3 id='associations-dans-les-modeles-5'>Associations dans les modèles</h3>
<p>
  Il faut maintenant déclarer dans les modèles concernés les associations de la façon suivante&nbsp;:
</p>
<pre class='prettyprint linenums'># app/models/comment.rb
class Comment &lt; ActiveRecord::Base
  belongs_to :commentable, :polymorphic =&gt; true
  ...
# app/models/event.rb
class Event &lt; ActiveRecord::Base
  has_many :comments, :as =&gt; :commentable
  ...
# app/models/photo.rb
class Photo &lt; ActiveRecord::Base
  has_many :comments, :as =&gt; :commentable
  ...
# app/models/article.rb
class Article &lt; ActiveRecord::Base
  has_many :comments, :as =&gt; :commentable
  ...</pre>
<h3 id='creation-d-un-commentaire-6'>Création d'un commentaire</h3>
<p>
  Si on veut maintenant créer un commentaire et l'associer à un article, on peut simplement faire&nbsp;
</p>
<pre class='prettyprint linenums'>@article.comments.create(:content =&gt; 'Mon contenu')</pre>
<h2 id='aller-plus-loin-7'>Aller plus loin</h2>
<h3 id='ressources-imbriquees-8'>Ressources imbriquées</h3>
<p>
  Si on veut généraliser et que l'on veut accéder par exemple à tous les commentaires d'un article par l'URL <span class="code">/articles/1/comments</span> il faut utiliser les ressources imbriquées et pour cela modifier les <span class="code">routes</span>.
</p>
<pre class='prettyprint linenums'># config/routes.rb
resources :model_name do
  resources :comments
end</pre>
<p>
  En faisant ça pour chaque modèle, la route <span class="code">/model/1/comments</span> redirigera alors vers l'action <span class="code">index</span> de <span class="code">CommentsController</span>. Et c'est dans cette méthode qu'il faut, en fonction du type de la ressource, afficher les commentaires.
</p>
<h3 id='recuperer-la-ressource-9'>Récupérer la ressource</h3>
<p>
  Ryan Bates nous propose dans son <a target="_blank" href="http://railscasts.com/episodes/154-polymorphic-association" rel="nofollow">RailsCast</a> une méthode pour récupérer la ressource concernée.
</p>
<pre class='prettyprint linenums'># app/controllers/comments_controller.rb
private
def find_commentable
  params.each do |name, value|
    # Regex correspondant à la forme model_id
    if name =~ /(.+)_id$/
      # $1 correspond au nom du modèle
      return $1.classify.constantize.find(value) 
    end
  end
  nil # Retourne nil si rien n'a été trouvé
end</pre>
<p>
  La méthode ci-dessus parcours tous les paramètres envoyés par le client et cherche un paramètre se terminant par <span class="code">_id</span>. Si nous étions à l'url <span class="code">/articles/1/comments</span>, nous aurions par exemple <span class="code">article_id</span> avec comme valeur 1.
</p>
<p>
  Si la méthode trouve une correspondance dans les paramètres, elle appelle la méthode <span class="code">classify</span> sur le nom du modèle. La méthode <a target="_blank" href="http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-classify" rel="nofollow">classify</a> transforme les chaînes de caractère s'apparentant à des noms de tables en des chaînes de caractère pouvant correspondre à des noms de classe. Par exemple&nbsp;
</p>
<pre class='prettyprint linenums'>&quot;egg_and_hams&quot;.classify # =&gt; &quot;EggAndHam&quot;
&quot;posts&quot;.classify        # =&gt; &quot;Post&quot;</pre>
<p>
  Puis, la méthode <a target="_blank" href="http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize" rel="nofollow">constantize</a> est appelé pour essayer de trouver une constante correspondante. «Article» deviendra alors la constante correspondant à la classe <code>Article</code>.
</p>
<p>
  Enfin, la méthode <code>find</code> est appelé pour récupérer l'objet en question.
</p>
<h3 id='afficher-et-creer-un-commentaire-10'>Afficher et créer un commentaire</h3>
<p>
  De cette façon, on peut maintenant afficher dans notre vue <span class="code">index</span> de <span class="code">comments</span>, tous les commentaires de l'objet concerné.
</p>
<pre class='prettyprint linenums'># app/controllers/comments_controller.rb
def index
  @commentable = find_commentable
  @comments    = @commentable.comments
end</pre>
<p>
  Et dans la vue :
</p>
<pre class='prettyprint linenums'># app/views/comments/index.html.erb
&lt;h1&gt;Liste des commentaires&lt;/h1&gt;
&lt;ul id=&quot;comments&quot;&gt;
  &lt;% @comments.each do |comment| %&gt;
    &lt;li&gt;&lt;%= comment.content %&gt;&lt;/li&gt;
  &lt;% end %&gt;
&lt;/ul&gt;
&lt;h2&gt;Nouveau commentaire&lt;/h2&gt;
&lt;% form_for [@commentable, Comment.new] do |form| %&gt;
  &lt;ol class=&quot;formList&quot;&gt;
    &lt;li&gt;
      &lt;%= form.label :content %&gt;
      &lt;%= form.text_area :content, :rows =&gt; 5 %&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;%= submit_tag &quot;Add comment&quot; %&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;% end %&gt;</pre>
<p>
  Et enfin, pour l'action <span class="code">create</span> du contrôleur&nbsp;
</p>
<pre class='prettyprint linenums'># app/controllers/comments_controller.rb
def create
  @commentable = find_commentable
  @comment = @commentable.comments.build(params[:comment])</pre>
<p>
  Voilà pour ce qui est des associations polymorphiques !
</p>
<h2 id='references-11'>Références</h2>
<ul>
  <li>
    <a href='http://railscasts.com/episodes/154-polymorphic-association'>Rails Casts</a>
    de Ryan Bates ;
  </li>
  <li>
    <a href='http://guides.rubyonrails.org/association_basics.html#polymorphic-associations'>ActiveRecord Association RailsGuides.</a>
  </li>
</ul>
]]></content:encoded><description>L'association polymorphique peut sembler compliquée et déroutante. En regardant d'un peu plus près, son utilisation n'est pas si difficile et peut être très utile ! C'est une association qui permet à un modèle d'appartenir à plusieurs autres modèles.</description><feedburner:origLink>http://ontherailsagain.com/articles/associations-polymorphiques</feedburner:origLink></item><item><title>Le routage de ressources en Rails</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/5uOl2Q7sPuM/le-routage-de-ressources-en-rails</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nicolas</dc:creator><pubDate>Mon, 31 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/le-routage-de-ressources-en-rails</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Le routage de ressources en Rails permet de déclarer très rapidement l'ensemble des routes pour un contrôleur qui respecte l'architecture REST. Cet article présente comment définir les routes pour des ressources.</p>
<div class='require'>
  <strong>Pré-requis&nbsp;:</strong>
  <ul>
    <li>
      Avoir compris le
      <a href='http://ontherailsagain.com/articles/comprendre-les-routes-en-rails' target='_blank'>fonctionnement des routes en rails</a>
    </li>
  </ul>
</div>
<div class='see'>
  <strong>Ce que nous allons voir&nbsp;:</strong>
  <ul>
    <li>Un rappel sur REST</li>
    <li>Définir des routes pour des ressources</li>
    <li>Ajouter des routes pour des actions spécifiques aux ressources</li>
  </ul>
</div>
<h2 id='rappel-sur-les-ressources-et-sur-rest-1'>Rappel sur les ressources et sur REST</h2>
<h3 id='notion-de-ressource-2'>Notion de ressource</h3>
<p>
  La notion de ressource est vague et donc de difficile à définir. Prenons la première définition explicite du terme <strong>ressource</strong> dans son sens le plus général donnée par
  <a href='http://tools.ietf.org/html/rfc2396' style='display:inline;' target='_blank'>Tim berners Lee</a>
  &nbsp;:
</p>
<blockquote cite='http://tools.ietf.org/html/rfc2396'>
  Une ressource peut être toute chose qui possède une identité. Des exemples familiers incluent un document électronique, une image, un service (par exemple "le bulletin météo d'aujourd'hui pour Los Angeles"), ou un ensemble d'autres ressources. Certaines ressources ne peuvent pas être "ramenées par le réseau" (network retrievable), par exemple les êtres humains, les entreprises, les livres d'une bibliothèque peuvent être aussi considérés comme des ressources.
</blockquote>
<a href='http://tools.ietf.org/html/rfc2396' target='_blank'></a>
<p>Ce qu'il est important de comprendre c'est qu'une ressource est finalement n'importe quoi que l'on peut <b>identifier de manière unique</b> par une URI (Uniform Resource Identifier). Sur le web, cet identifiant unique est généralement une URL.</p>
<p>Même si cette notion paraît difficile à appréhender aux premiers abords, elle vous paraîtra plus claire une fois utilisée dans une application. Passons donc à la suite et à une approche de l'architecture REST.</p>
<h3 id='notion-de-rest-3'>Notion de REST</h3>
<p><strong>REST</strong> est un style architectural, une manière de construire une application pour le web. Les principes essentiels d'une architecture REST sont les suivants&nbsp;:</p>
<ul>
  <li>
    Chaque ressource doit être identifiée de manière <b>unique</b> par une URI.
  </li>
  <li>
    Les méthodes HTTP <code>GET</code>, <code>POST</code>, <code>PUT</code> et <code>DELETE</code> suffisent pour <b>accéder à</b> et <b>modifier</b> une ressource.
  </li>
</ul>
<h3 id='exemple-d-application-restful-4'>Exemple d'application RESTful</h3>
<p>
  Je pense qu'il n'y a pas plus parlant qu'un exemple pour comprendre ce qu'est l'architecture REST et ce qu'est une ressource. <br />
  Prenons donc l'exemple d'un blog contenant plusieurs articles. Ici, les ressources à manipuler sont les articles. Dans ce blog on peut ajouter, modifier, lire, et supprimer des articles. Chaque article a un identifiant unique, ici c'est son nom. Donc, pour que l'application respecte l'architecture REST elle doit permettre les actions suivantes&nbsp;:
</p>
<ul>
  <li><b>Lire un article</b> - on effectue une requête de type <code>GET</code> sur <i>http://monblog.fr/articles/nom-de-mon-article</i>. Le nom de l'article étant son identifiant unique.</li>
  <li><b>Écrire un article</b> - on effectue une requête de type <code>POST</code> sur <i>http://monblog.fr/articles/</i>. Le contenu du message <code>POST</code> représentant le contenu du nouvel article à créer.</li>
  <li><b>Modifier un article</b> - on effectue une requête de type <code>PUT</code> sur <i>http://monblog.fr/articles/nom-de-mon-article</i>. Le contenu du message <code>PUT</code> représentant le contenu modifié de l'article.</li>
  <li><b>Supprimer un article</b> - on effectue une requête de type <code>DELETE</code> sur <i>http://monblog.fr/articles/nom-de-mon-article</i>.</li>
</ul>
<p>
  Si vous avez besoin de plus d'informations au sujet de REST reportez vous à la section REST de l'article
  <a href='http://ontherailsagain.com/articles/avant-de-commencer-avec-ruby-on-rails#3-rest-representational-state-transfer' target='_blank'>Avant de commencer avec Ruby On Rails</a>
</p>
<h2 id='les-routes-pour-des-ressources-5'>Les routes pour des ressources</h2>
<h3 id='crud-methodes-http-et-actions-6'>CRUD, méthodes HTTP et actions</h3>
<p>
  En Rails, le routage de ressources fournit une correspondance entre les <strong>verbes HTTP et les URLs</strong> avec les <strong>actions du contrôleur</strong>. Par convention, chaque action du contrôleur correspond à une <strong>opération CRUD</strong> (create, read, update, destroy) dans la base de données.
</p>
<p>
  Prenons un exemple, supposons que nous avons un blog contenant des articles qui sont ici les ressources à manipuler. Voici comment définir les routes pour ce type de ressources&nbsp;:
</p>
<pre class='prettyprint linenums'># config/routes.rb
resources :articles</pre>
<p>Cette seule règle permet de définir les routes pour les actions <code>index</code>, <code>show</code>, <code>new</code>, <code>edit</code>, <code>create</code>, <code>update</code> et <code>destroy</code>, qui sont les actions typiques que l'on doit pouvoir effectuer sur une ressource.</p>
<p>Nous obtenons les sept routes suivantes qui s'appliquent toutes au contrôleur <code>articles_controller</code>&nbsp;:</p>
<table>
  <thead>
    <tr>
      <th>Méthode <br />HTTP</th>
      <th>URL</th>
      <th>Action</th>
      <th>Utilité</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles</span></td>
      <td>index</td>
      <td>Afficher la liste de tous les articles</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/new</span></td>
      <td>new</td>
      <td>Afficher un formulaire pour créer un article</td>
    </tr>
    <tr>
      <td>POST</td>
      <td><span class="code">/articles</span></td>
      <td>create</td>
      <td>Créer un nouvel article à partir du contenu du message <code>POST</code></td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:id</span></td>
      <td>show</td>
      <td>Afficher l'article ayant pour id celle passée dans l'URL</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/articles/:id/edit</span></td>
      <td>edit</td>
      <td>Afficher un formulaire pour editer l'article ayant pour id celle passée dans l'URL</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td><span class="code">/articles/:id</span></td>
      <td>update</td>
      <td>Mettre à jour un article ayant pour id celle passée dans l'URL à partir du corps du message <code>PUT</code></td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td><span class="code">/articles/:id</span></td>
      <td>destroy</td>
      <td>Supprimer l'article ayant pour id celle passée dans l'URL</td>
    </tr>
  </tbody>
</table>
<p class='warning'>Il est important de savoir qu'il y a une priorité sur les règles. Les règles écrites au début du fichier sont prioritaires par rapport à celles écrites en dessous.</p>
<h3 id='chemins-et-urls-generes-7'>Chemins et URLs générés</h3>
<p>Comme pour toutes les routes, le routage de ressources génère des chemins et des URLs. Voici un tableau récapitulatif de ces helpers et des actions vers lesquelles ils redirigent en fonction du verbe HTTP employé&nbsp;:</p>
<table>
  <thead>
    <tr>
      <th>Path helper</th>
      <th>Méthode <br />HTTP</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan='2'><span class="code">articles_path</span></td>
      <td>GET</td>
      <td>index</td>
    </tr>
    <tr>
      <td>POST</td>
      <td>create</td>
    </tr>
    <tr>
      <td rowspan='3'><span class="code">article_path(:id)</span> Ce path prend en paramètre l'id de l'article à modifier</td>
      <td>GET</td>
      <td>show</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td>update</td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td>destroy</td>
    </tr>
    <tr>
      <td><span class="code">new_article_path</span></td>
      <td>GET</td>
      <td>new</td>
    </tr>
    <tr>
      <td><span class="code">edit_article_path</span></td>
      <td>GET</td>
      <td>edit</td>
    </tr>
  </tbody>
</table>
<p class='notice'>Comme tous les routes helpers, il y a aussi les URLs helpers qui sont générés. Pour s'en servir, il suffit de remplacer <span class="code">…_path</span> par <span class="code">…_url</span>. Par exemple, <span class="code">new_article_url</span>.</p>
<h3 id='exemple-d-utilisations-8'>Exemple d'utilisations</h3>
<p>Le routage de ressource est utilisé par Rails lorsque l'on crée un scaffold. Rails génère les routes, le modèle, la table en base de données, les actions RESTful dans le contrôleur et les vues. Donc pour voir un bon exemple des <code>path_heplers</code>, il suffit de regarder dans les vues générées.</p>
<p>Par exemple, si on crée le scaffold suivant&nbsp;:</p>
<pre class='prettyprint linenums'>$ rails generate scaffold Article title:string content:text</pre>
<p>On peut constater l'utilisation des <code>path_helpers</code> suivants :</p>
<pre class='prettyprint linenums'># app/views/articles/index.html.erb
...
&lt;%= link_to 'New Article', new_article_path %&gt;
...</pre>
<pre class='prettyprint linenums'># app/views/articles/show.html.erb
...
# Ici @article est défini dans la méthode show du contrôleur articles_controller
&lt;%= link_to 'Edit', edit_article_path(@article) %&gt; |
&lt;%= link_to 'Back', articles_path %&gt;
...</pre>
<pre class='prettyprint linenums'># app/views/articles/show.html.erb
...
# Ici @article est défini dans la méthode edit du contrôleur articles_controller
&lt;%= link_to 'Show', @article %&gt; |
&lt;%= link_to 'Back', articles_path %&gt;
...</pre>
<p>Pour le dernier exemple, on peut voir que le lien pour l'action <code>show</code> n'utilise pas le <code>path_helper</code> <span class="code">article_path(@article)</span>. Ceci est dû au fait que Rails comprend tout seul que lorsqu'on lui passe directement une instance de l'objet <b>Article</b> il doit utiliser le <code>path_helper</code> <span class="code">article_path</span> et donc on fonction de la méthode HTTP utilisé il redirigera vers la bonne action du contrôleur. Ici c'est un lien donc c'est la méthode <code>GET</code> qui est utilisé et donc ce lien redirigera vers l'action <code>show</code>.</p>
<h3 id='definir-plusieurs-ressources-9'>Définir plusieurs ressources</h3>
<p>Le routeur Rails nous permet de définir plusieurs ressources en une seule ligne de la façon suivante&nbsp;:</p>
<pre class='prettyprint linenums'>resources :articles, :photos, :authors</pre>
<h2 id='les-routes-pour-une-ressource-unique-10'>Les routes pour une ressource unique</h2>
<h3 id='crud-methodes-http-et-actions-11'>CRUD, méthodes HTTP et actions</h3>
<p>Il peut arriver que l'on ait besoin de définir les routes pour une ressource unique à laquelle on aimerait accéder sans préciser une ID. Le routeur Rails nous permet de définir ce genre de route. Prenons un exemple pour voir l'ensemble des routes créées.</p>
<pre class='prettyprint linenums'># config/routes.rb
resource :account</pre>
<p class='warning'>Faire attention, dans ce cas il n'y a pas de « s » au mot <span class="code">resource</span></p>
<p>Cette seule règle permet de définir les routes pour les actions <code>show</code>, <code>new</code>, <code>edit</code>, <code>create</code>, <code>update</code> et <code>destroy</code> du contrôleur <code>accounts_controller</code>. Voici un récapitulatif&nbsp;:</p>
<table>
  <thead>
    <tr>
      <th>Méthode <br />HTTP</th>
      <th>URL</th>
      <th>Action</th>
      <th>Utilité</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GET</td>
      <td><span class="code">/account/new</span></td>
      <td>new</td>
      <td>Afficher un formulaire pour créer un compte</td>
    </tr>
    <tr>
      <td>POST</td>
      <td><span class="code">/account</span></td>
      <td>create</td>
      <td>Créer le nouveau compte à partir du contenu du message <code>POST</code></td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/account</span></td>
      <td>show</td>
      <td>Afficher le seul et unique compte</td>
    </tr>
    <tr>
      <td>GET</td>
      <td><span class="code">/account/edit</span></td>
      <td>edit</td>
      <td>Afficher un formulaire pour editer le compte</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td><span class="code">/account</span></td>
      <td>update</td>
      <td>Mettre à jour le seul et unique compte à partir du contenu du message <code>PUT</code></td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td><span class="code">/account</span></td>
      <td>destroy</td>
      <td>Supprimer le compte</td>
    </tr>
  </tbody>
</table>
<h3 id='chemins-et-urls-generes-12'>Chemins et URLs générés</h3>
<p>Dans la ces d'une ressource unique, les <code>path_helpers</code> générés ne prennent pas de paramètre étant donné que la ressource à modifier est toujours la même. Voici un tableau récapitulatif de ces helpers et des actions vers lesquelles ils redirigent en fonction du verbe HTTP employé&nbsp;:</p>
<table>
  <thead>
    <tr>
      <th>Path helper</th>
      <th>Méthode <br />HTTP</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan='4'><span class="code">account_path</span></td>
      <td>GET</td>
      <td>show</td>
    </tr>
    <tr>
      <td>POST</td>
      <td>create</td>
    </tr>
    <tr>
      <td>PUT</td>
      <td>update</td>
    </tr>
    <tr>
      <td>DELETE</td>
      <td>destroy</td>
    </tr>
    <tr>
      <td><span class="code">new_account_path</span></td>
      <td>GET</td>
      <td>new</td>
    </tr>
    <tr>
      <td><span class="code">edit_account_path</span></td>
      <td>GET</td>
      <td>edit</td>
    </tr>
  </tbody>
</table>
<h2 id='ajouter-des-actions-restful-13'>Ajouter des actions RESTful</h2>
<p>Il arrive souvent que l'on ait besoin d'ajouter des routes à une ressource pour des actions autres que celles définies par défaut. Le routeur Rails nous permet de le faire très simplement, voyons comment.</p>
<h3 id='ajout-d-une-action-sur-la-collection-14'>Ajout d'une action sur la collection</h3>
<p>Tout d'abord, il faut définir si cette action va agir sur <b>l'ensemble des ressources</b> ou seulement sur <b>une seule</b>. Prenons un exemple, supposons que l'on ait un contrôleur <code>photos_controller</code> et que l'on veuille ajouter la possiblité de faire une recherche sur les photos. Dans ce cas, l'action sera effectuée sur l'ensemble des ressources photos. Donc on défini les routes comme ceci&nbsp;:</p>
<pre class='prettyprint linenums'>resources :photos do
  get 'search', :on =&gt; :collection
end</pre>
<p class='notice'>Il est possible d'utiliser des symboles à la place des chaînes de caractères. Par exemple, on pourrait écrire&nbsp;: <br /><span class="code">get :search, :on => :collection</span></p>
<h3 id='ajout-d-une-action-sur-un-membre-15'>Ajout d'une action sur un membre</h3>
<p>Supposons maintenant que l'on veuille effectuer une action sur une seule ressource, par exemple accéder à une previsualisation d'une photo. Dans ce cas on peux définir les routes comme ceci&nbsp;:</p>
<pre class='prettyprint linenums'>resources :photos do
  get 'preview', :on =&gt; :member 
end</pre>
<p>Les routes helpers obtenus dans les deux cas précédents sont respectivement <span class="code">search_photos_path</span> et <span class="code">preview_photo_path</span>. Bien faire attention au « s » à la fin de photos que l'on met que lorsque l'action est sur la collection entière.</p>
<p>Si on a beaucoup d'actions à ajouter sur les membres ou sur la collection entière on peut également définir les routes comme ceci :</p>
<pre class='prettyprint linenums'>resources :photos do
  member do
    get 'preview'
    get 'buy'
  end
  collection do
    get 'search'
    get 'another_action'
  end
end</pre>
<p class='notice'>Il faut noter ici que l'on peut remplacer let mot <span class="code">get</span> par les autres méthodes HTTP, par exemple <span class="code">post</span></p>
<p>Voilà les bases pour le routage de ressources en Rails, je publierai prochainement un article sur les ressources imbriquées. Si vous avez des questions ou améliorations à proposer n'hésitez pas à laissez un commentaire.</p>
<h2 id='references-16'>Références</h2>
<ul>
  <li>
    <a href='http://guides.rubyonrails.org/routing.html' target='_blank'>Guide Rails - Rails Routing from the Outside In</a>
  </li>
</ul>
]]></content:encoded><description>Cet article présente la manière de définir les routes en Rails pour des ressources ainsi que comment ajouter des actions pour ces ressources. Il présente également l'ensemble des routes helpers générés ainsi que leurs utilisations avec les différents verbes HTTP.</description><feedburner:origLink>http://ontherailsagain.com/articles/le-routage-de-ressources-en-rails</feedburner:origLink></item><item><title>Mettre en place son environnement Ruby On Rails sous Mac OS X Lion</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/4Mr05HuT9O0/mettre-en-place-son-environnement-ruby-on-rails-sous-mac-os-x-lion</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nima</dc:creator><pubDate>Mon, 24 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/mettre-en-place-son-environnement-ruby-on-rails-sous-mac-os-x-lion</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>mettre en place son environnement Ruby On Rails ;</li>
    <li>installer MySQL et PostgreSQL ;</li>
    <li>les bases de RVM.</li>
  </ul>
</div>
<h2 id='l-environnement-ruby-1'>L'environnement Ruby</h2>
<h3 id='installer-les-outils-developpeurs-2'>Installer les outils développeurs</h3>
<p>
  Le language Ruby est fourni avec les outils développeurs Mac OS X, donc pour avoir son environnement Ruby fonctionnel il suffit d'installer XCode.
  Si vous avez fait une mise à jour depuis Snow Leopard et que vous vous retrouvez avec un tas de bugs mystiques je vous conseille grandement de réinstaller XCode pour que les liens des librairies soient mis à jour.
  Voilà la commande à taper dans un terminal pour supprimer totalement XCode&nbsp;:
</p>
<pre class='prettyprint linenums'>$ sudo /Developer/Library/uninstall-devtools –mode=all</pre>
<h3 id='installer-rails-3'>Installer Rails</h3>
<p>
  Et bien voilà, vous pouvez maintenant installer le framework Ruby On Rails.
</p>
<pre class='prettyprint linenums'>$ gem install rails</pre>
<p>
  Vous pouvez maintenant réinstaller XCode fraichement !
</p>
<h2 id='installer-mysql-5-5-4'>Installer MySQL (5.5)</h2>
<p>
  Le plus simple reste de passer par
  <a href='http://dev.mysql.com/downloads/mysql/' target='_blank'>l'image fournit sur le site de MySQL</a>
  et d'installer tout ce qui se trouve à l'intérieur.
</p>
<p>
  Pour ma part, j'ai pris la version 64bit&nbsp;:
  <a href='http://dev.mysql.com/downloads/mirror.php?id=404216' target='_blank'>Mac OS X ver. 10.6 (x86, 64-bit), DMG Archive.</a>
</p>
<p>
  Pour savoir si vous êtes en 64 bits, lancez l'application <i>Information Système</i>, cliquez sur <i>Logiciel</i> et regardez si votre noyau est en 64bits.
</p>
<p>
  Sinon, en ligne de commande&nbsp;:
</p>
<pre class='prettyprint linenums'>$ sysctl hw |grep 64bit
&gt; hw.cpu64bit_capable: 1 # Vous êtes en 64 bits
&gt; hw.cpu64bit_capable: 0 # Vous n'êtes pas en 64 bits</pre>
<p>
  Une fois l'installation faite, il faut penser à rajouter le chemin des binaires MySQL à votre PATH.
  Pour que votre PATH et vos librairies dynamiques soient bien à jour, rajouter les lignes qui suivent dans le fichier <b>.profile</b> qui se trouve à la racine de votre home. (Exemple: /Users/Nima/.profile ou ~/.profile).
</p>
<pre class='prettyprint linenums'># ~/.profile
export PATH=&quot;$PATH:/usr/local/mysql/bin&quot;
export DYLD_LIBRARY_PATH=&quot;$DYLD_LIBRARY_PATH:/usr/local/mysql/lib&quot;</pre>
<p>
  Si le fichier n'existe pas, vous pouvez le créer en utilisant la commande <span class="code">touch</span>.
</p>
<pre class='prettyprint linenums'>$ touch ~/.profile</pre>
<p>
  Sachez que vous pourrez lancer ou arrêter MySQL à partir de vos préférences système. Une icône de MySQL doit se trouver dans la partie «autre».
</p>
<h2 id='installer-postgresql-9-1-1-5'>Installer PostgreSQL (9.1.1)</h2>
<h3 id='installation-de-postgresql-6'>Installation de PostgreSQL</h3>
<p>
  Encore une fois, le plus simple reste de passer par
  <a href='http://www.enterprisedb.com/products-services-training/pgdownload' target='_blank'>l'image fournit par PostgreSQL.</a>
</p>
<p>
  L'installation va vous demander de redémarrer. Faite le puis relancez l'image et l'installation.
  Pensez à bien spécifier un mot de passe pour l'utilisateur postgres.
</p>
<p>
  Une fois l'installation faite, il faut créer un utilisateur.
</p>
<h3 id='creation-d-un-utilisateur-7'>Création d'un utilisateur</h3>
<p>
  Voilà la commande à taper dans votre terminal pour créer un utilisateur. Ici le nom d'utilisateur sera <b>admin</b>.
  L'option <span class="code">--username</span> permet de spécifier que cette action doit être éxécuter par l'utilisateur <b>postgres</b> et l'option <span class="code">--pwprompt</span> force la demande d'un mot de passe.
</p>
<pre class='prettyprint linenums'>$ createuser admin --superuser --pwprompt --username postgres
Enter password for new role: # password pour l'utilisateur admin
Enter it again:
Password: # celui que vous avez entré pendant l'installation de postgres</pre>
<h2 id='installer-rvm-8'>Installer RVM</h2>
<p>
  <a href='http://beginrescueend.com/' target='_blank'>RVM</a>
  est un outil très utile si l'on veut utiliser des versions de Ruby différentes pour plusieurs projets ou si on veut séparer ses gems d'un projet à un autre.
  Pour l'installer, il suffit de faire ce qui est indiqué sur le site officiel, autrement dit, éxécuter ce qui suit dans un terminal.
</p>
<pre class='prettyprint linenums'>$ bash &lt; &lt;(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)</pre>
<p>
  Puis, comme indiqué à la fin de l'installation, ajoutez ce qui suit dans votre <b>.profile</b>&nbsp;:
</p>
<pre class='prettyprint linenums'># ~/.profile
[[ -s &quot;/Users/Nima/.rvm/scripts/rvm&quot; ]] &amp;&amp; source &quot;/Users/Nima/.rvm/scripts/rvm&quot;  # This loads RVM into a shell session.</pre>
<h3 id='les-gem-et-les-gemsets-9'>Les Gem et les Gemsets</h3>
<p>
  Il est possible que vous vous demandiez ce qu'est une Gem. Est bien c'est simple, comme l'indique la doc de
  <a target='_blank' href='http://docs.rubygems.org/read/chapter/1'>RubyGems.org</a>,
  une gem est une application Ruby sous forme de paquet ou de librairie. Par exemple, Rails est une gem.
</p>
<p>
  Les gemsets sont des ensembles de gems et chaque ensemble est associé à un projet / environnement de travail spécifique.
</p>
<p>
  Supposons que vous vouliez utiliser la version 1.9.2 de Ruby pour votre projet. Commencez par l'installer, comme ceci&nbsp;:
</p>
<pre class='prettyprint linenums'>$ rvm install 1.9.2</pre>
<p>
  Puis spécifiez à RVM que vous voulez utiliser cette version dans le terminal courant.
</p>
<pre class='prettyprint linenums'>$ rvm use 1.9.2</pre>
<p class='notice'>
  Pour utiliser une version par défaut, rajouter l'option <span class='code'>--default</span>. Par exemple, <span class="code">rvm use --default 1.9.2</span>.
</p>
<p>
  Maintenant vous pouvez créer un Gemset et spécifier que vous voulez utiliser la version 1.9.2 pour votre projet.
</p>
<pre class='prettyprint linenums'>$ rvm gemset create mon_projet
$ rvm use 1.9.2@mon_projet</pre>
<p>
  A partir de là, toute les gems que vous allez installer seront installées dans le Gemset que vous venez de créer.
</p>
<p>
  Pour éviter de devoir retaper <span class='code'>rvm use 1.9.2@mon_projet</span> vous pouvez vous faire des alias dans votre <b>.profile</b>.
</p>
<pre class='prettyprint linenums'># ~/.profile
alias mon_projet=&quot;rvm use 1.9.2@mon_projet; cd ~/Development/Rails/mon_projet&quot;</pre>
<p>
  De cette façon vous n'aurez qu'a taper une commande dans le terminal pour vous trouver dans bon dossier de travail et utiliser le bon Gemset.
</p>
<h3 id='bundler-10'>Bundler</h3>
<p>
  <a href='http://gembundler.com/' target='_blank'>Bundler</a>
  est un gestionnaire de dépendance pour gérer les Gems de votre projet.
  Donc au lieu d'installer toutes les dépendances de vos projet les unes après les autres, vous les listerez dans le <b>Gemfile</b> de votre application, et il ne suffira que d'une commande pour que
  tout s'installe correctement. Autant vous dire que c'est un outil quasi indispensable !
</p>
<p>Cessons de discuter ! Voilà comment installer le gem Bundler...</p>
<pre class='prettyprint linenums'>$ gem install bundler</pre>
<p>
  Et pour lancer l'installation des gems listées dans le fichier <b>Gemset</b> de votre application Rails, il suffit de se placer à la racine de votre application et de lancer la commande suivante&nbsp;:
</p>
<pre class='prettyprint linenums'>$ bundle install</pre>
<p>
  Donc suivant le système de gestion de base de données que vous voulez utiliser, il suffit de mettre une des deux lignes suivantes dans le fichier Gemfile puis d'éxécuter à nouveau la commande
  <span class="code">bundle install</span>.
</p>
<pre class='prettyprint linenums'># Gemfile
gem 'pg'      # Pour PostgreSQL
gem 'mysql2'  # Pour MySQL</pre>
<p>
  Voilà pour votre environnement Rails ! Vous devriez être «Up and running!» comme disent les anglais !
</p>
<p>
  Si ça ne marche pas n'hésitez pas à nous laissez un commentaire, nous pourrons essayer de vous aider !
</p>
]]></content:encoded><description>Une chose qui peut poser des problèmes avant de se lancer dans l'utilisation du framework Ruby On Rails est d'avoir un environnement fonctionnel.C'est pourquoi dans cet article je fais le tour des choses indispensables à avoir sur sa machine et j'explique comment les installer.</description><feedburner:origLink>http://ontherailsagain.com/articles/mettre-en-place-son-environnement-ruby-on-rails-sous-mac-os-x-lion</feedburner:origLink></item><item><title>Comprendre les routes en Rails</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/W7_faXEjGH8/comprendre-les-routes-en-rails</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nicolas</dc:creator><pubDate>Wed, 19 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/comprendre-les-routes-en-rails</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>
      Le fonctionnement du routeur Rails.
    </li>
    <li>
      Les utilisations de bases.
    </li>
  </ul>
</div>
<h2 id='comprendre-le-fonctionnement-1'>Comprendre le fonctionnement</h2>
<p>Voici une schéma explicatif permettant de comprendre le rôle du routeur dans le fonctionnement d'une application Rails.</p>
<img alt='Représentation schématique du fonctionnement des routes' src='http://ontherailsagain.com/article_images/comprendre_les_routes/Routes.png' title='Schéma du fonctionnement des routes' />
<p>Le processus commence avec une requête faite à partir du navigateur. Cette requête est ensuite transmise au routeur Rails qui l'analyse et extrait les informations suivantes&nbsp;:</p>
<ul>
  <li>le contrôleur à instancier ;</li>
  <li>l'action (correspondant à une méthode) à appeler dans ce contrôleur ;</li>
  <li>enfin, si il y en a, les paramètres à passer à cette méthode.</li>
</ul>
<p>Lorsqu'il reçoit une URL correctement formattée, le routeur Rails instancie le contrôleur spécifié et appelle la méthode appropriée en lui passant les paramètres si besoin. Le contrôleur va donc effectuer les actions nécessaires et Rails renverra la vue correspondante. Cette vue sera ensuite renvoyée au navigateur. Cette explication est volontairement simplifiée mais elle montre l'importance du routeur Rails.</p>
<p>Par contre si le routeur Rails reçoit une URL mal formattée, il sera incapable d'effectuer les bonnes actions. Il est donc très important que le format de l'URL soit correct, c'est pourquoi le routeur Rails à également une deuxième fonction&nbsp;: nous aider à générer de bonnes URLs.</p>
<p>Donc pour synthétiser, le routeur Rails à deux fonctions principales&nbsp;:</p>
<ul>
  <li><strong>connecter des URLs au code</strong>, c'est à dire les interpreter, instancier le bon contrôleur et enfin appeler les bonnes actions ;</li>
  <li><strong>générer des chemins et des URLs</strong> sans avoir besoin de les écrire «à la main» dans le code.</li>
</ul>
<p>Le routeur Rails effectue ces deux fonctions en utilisant les règles de routage définies dans le fichier <i>config/routes.rb</i>. Voyons chacune de ces fonctions un peu plus en détail.</p>
<h2 id='connecter-les-urls-au-code-2'>Connecter les URLs au code</h2>
<p>Prenons un exemple, supposons que j'ai écris une fonction <code>new</code> dans le contrôleur <code>articles_controller</code>. J'aimerais que cette méthode soit éxecutée lorsque j'accède à l'URL suivante&nbsp;: <i>www.monsite.fr/articles/new</i>.</p>
<p>Pour cela, il suffit simplement de définir la règle suivante dans le fichier <i>config/routes.rb</i>&nbsp;:</p>
<pre class='prettyprint linenums'># config/routes.rb
match &quot;articles/new&quot; =&gt; &quot;articles#new&quot;</pre>
<p>Décorticons un peu cette règle. Tout d'abord on définit l'URL que notre routeur doit reconnaître avec la première partie de la règle : <span class="code">match "articles/new"</span>.</p>
<p class='notice'>On note qu'il n'y a pas besoin de préciser le nom de domaine, ceci est dû au fait que notre routeur ce trouve dans notre application et que notre application est accessible via son nom de domaine.</p>
<p>Ensuite on précise quelle partie de code doit être éxécutée lorsque l'on pointe vers cette URL, avec la seconde partie de la règle <span class="code">=> "articles#new"</span>. Ce qui se trouve à gauche du # correspond au contrôleur à instancier et ce qui se trouve à droite correspond à la méthode à appeler.</p>
<p>Rails nous permet également de définir la même règle plus simplement :</p>
<pre class='prettyprint linenums'># config/routes.rb
get &quot;articles/new&quot;</pre>
<p>Voilà un exemple de la première utilité du routeur Rails qui est de relier les URLs au code, passons maintenant à la seconde utilité de ce routeur.</p>
<h2 id='generer-des-chemins-et-des-urls-3'>Générer des chemins et des URLs</h2>
<h3 id='un-peu-de-theorie-4'>Un peu de théorie</h3>
<p>Le routeur permet également de générer des routes helpers qui sont des méthodes qui renvoies une URL correctement formattée. En effet, si vous avez écrit la  règle précedente dans votre fichier <i>config/routes.rb</i> et que vous tapez la commande suivante dans un terminal à la racine de votre application :</p>
<pre class='prettyprint linenums'>$ rake routes</pre>
<p>vous obtiendrez ceci :</p>
<pre class='prettyprint linenums'>new_article GET /articles/new(.:format) {:controller =&gt; &quot;articles&quot;, :action =&gt; &quot;new&quot;}</pre>
<p>A partir de cette ligne on peut extraire les informations suivantes :</p>
<ul>
  <li>Le <strong>prefixe du helper</strong>, qui est ici <span class="code">new_article</span></li>
  <li>La <strong>méthode HTTP</strong> utilisé, ici c'est GET.</li>
  <li>Le <strong>format de l'URL</strong>, ici c'est <span class="code">/articles/new(.:format)</span>.</li>
  <li>Le <strong>contrôleur</strong> qui sera appelé si on accède à cette URL</li>
  <li>Et enfin, l'<strong>action</strong> du contrôleur qui sera appelée.</li>
</ul>
<p>A partir du préfixe, on obtient le nom des deux helpers générés à savoir <span class="code">new_article_path</span> et <span class="code">new_article_url</span>. La différence entre les deux est tout simplement que la version URL contient le nom de domaine et le port en plus du chemin. Par exemple :</p>
<ul>
  <li><span class="code">new_article_path</span> redirige vers <span class="code">/articles/new(.:format)</span></li>
  <li>alors que <span class="code">new_article_url</span> redirige vers <span class="code">http://www.monsite.fr/articles/new(.:format)</span></li>
</ul>
<p class='notice'>Dans l'exemple précédent, le numéro du port n'est pas indiqué car c'est le port HTTP par défaut à savoir le port 80.</p>
<h3 id='utilisation-de-ces-helpers-5'>Utilisation de ces helpers</h3>
<p>Les helpers générés par le routeur Rails peuvent s'utiliser dans la vue et rendent le code plus facile à lire et plus fiable puisque qu'on est sûr que l'URL sera bien formatée. Par exemple pour faire un lien interne qui redirige vers <i>www.monsite.fr/articles/new</i> on peut tout simplement faire comme ça :</p>
<pre class='prettyprint linenums'>&lt;%= link_to &quot;Créer un nouvel article&quot;, new_article_path %&gt;</pre>
<p>Voilà pour ce qui est des bases des routes en Rails. Je publierai d'autres articles pour détailler les différentes manières de définir les règles dans le fichier routes.rb. Si vous avez des questions ou des améliorations à proposer n'hésitez pas à laisser un commentaire.</p>
<h2 id='references-6'>Références</h2>
<ul>
  <li>
    <a href='http://darynholmes.wordpress.com/2008/03/15/beginners-tutorial-routing-in-rails-20-with-rest-part-1-of-n/'>Beginners Tutorial: Routing in Rails 2.0</a>
  </li>
  <li>
    <a href='http://guides.rubyonrails.org/routing.html'>Guide Rails : Rails Routing from the Outside In</a>
  </li>
</ul>
]]></content:encoded><description>Dès lors que l'on veut créer une application Rails on a besoin de modifier le fichier routes.rb. Cependant, l'utilité et le fonctionnement du routeur Rails ne sont pas forcément évidents. Cet article présente les bases et les buts du routeur Rails.</description><feedburner:origLink>http://ontherailsagain.com/articles/comprendre-les-routes-en-rails</feedburner:origLink></item><item><title>Les associations Many-to-Many avancées</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/koAMb7d-7og/les-associations-many-to-many-avancees</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nima</dc:creator><pubDate>Sun, 16 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/les-associations-many-to-many-avancees</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='require'>
  Pré-requis :
  <ul>
    <li>
      avoir vu les associations
      <a href='http://ontherailsagain.com/articles/les-associations-many-to-many' target='_blank'>Many-to-Many simples.</a>
    </li>
  </ul>
</div>
<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>stocker des informations relatives à une relation Many-to-Many ;</li>
    <li>utiliser et manipuler les associations.</li>
  </ul>
</div>
<h2 id='presentation-du-probleme-1'>Présentation du problème</h2>
<p>
  Avec les relations Many-to-Many nous avons déjà réussi à résoudre un certain nombre de problèmes pour ce qui était des relations entre deux objets.
  Allons encore plus loin.
  Supposons que vous vouliez stocker des informations supplémentaires et relatives à votre relation. Des propriétés propres à la relation et non aux objets liés.
</p>
<h2 id='un-exemple-concret-2'>Un exemple concret</h2>
<p>
  Illustrons le problème.
  Supposons que nous avons deux modèles : <span class="code">Doctor</span> et <span class="code">Patient</span>.
</p>
<p>
  Un docteur a plusieurs patients et un patient peut avoir plusieurs docteurs.
  Pour gérer les rendez-vous, nous avons besoin de savoir la date du prochain rendez-vous entre le docteur D et le patient P.
</p>
<h2 id='dans-la-theorie-3'>Dans la théorie</h2>
<p>
  Il nous faut une table de jointure entre ces modèles avec la référence du docteur, la référence du patient et des champs qui décrivent le rendez-vous.
  Cette approche est très similaire à une relation Many-to-Many classique à la différence que cette table ne stocke pas uniquement des références.
</p>
<p>
  Voici tout ce qui diffère d'une relation Many-to-Many classique :
</p>
<ul>
  <li>
    Le stockage en base de données est différent, la table de jointure <b>doit</b> avoir une colonne clé primaire.
    (contrairement à la relation Many-to-Many classique où l'on ne veut justement pas de clé primaire).
  </li>
  <li>
    Il faut créer un modèle pour cette relation. Donc un modèle correspondant à la table en base de donnée.
  </li>
  <li>
    Il n'y a pas de convention pour le nom de la table. Nous ne sommes pas obligé d'appeler la table <code>DoctorPatients</code>.
    Il est même conseillé de donner un nom plus adéquat pour ces tables. Nous l'appellerons <code>Appointments</code>.
  </li>
</ul>
<h2 id='dans-la-pratique-4'>Dans la pratique</h2>
<p>Avant de continuer, voilà une représentation de la relation des modèles entre eux.</p>
<img alt='Représentation schématique de la relation Many to Many avancées' src='http://ontherailsagain.com/article_images/Associations_Many-to-Many_avancees/Many-to-Many.png' title="Schéma de l'association Many to Many avancées" />
<h3 id='preparer-la-base-de-donnees-5'>Préparer la base de données</h3>
<p>
  Créons rapidement les modèles <code>Doctor</code> et <code>Patient</code>.
</p>
<pre class='prettyprint linenums'>$ rails generate scaffold Doctor  name:string speciality:string
$ rails generate scaffold Patient name:string</pre>
<p>
  Comme je vous l'ai dit, il est nécessaire de créer un modèle correspondant à la table de jointure&nbsp;:
</p>
<pre class='prettyprint linenums'>$ rails generate model Appointment</pre>
<p>
  On ne crée que le modèle car aucune vue ou contrôleur n'a besoin d'y être associé. De plus, le fait de passer par la commande rails permet d'avoir le modèle et la migration générés en une fois.
  Il faut maintenant éditer la migration générée pour qu'elle corresponde à ce que l'on veut&nbsp;:
</p>
<pre class='prettyprint linenums'># db/migrate/x_create_appointments.rb
class CreateAppointments &lt; ActiveRecord::Migration
  def self.up
    create_table :appointments do |t|
      t.references :doctor, :patient
      t.datetime   :appointment_date
      t.timestamps
    end
    add_index :appointments, [:doctor_id, :patient_id]
  end
  def self.down
    drop_table :appointments
  end
end</pre>
<p>
  Comme dans la relation Many-to-Many classique, on spécifie les références aux modèles <code>Doctor</code> et <code>Patient</code> .
  Puis on rajoute les informations nécéssaires à la description de la relation entre les deux objets.
  On peut également rajouter les indexes pour <span class="code">doctor_id</span> et <span class="code">patient_id</span> qui sont les clés qui serviront à la base de données lors de la recherche dans la table.
</p>
<p class='notice'>
  On notera que cette table <b>DOIT</b> avoir une clé primaire, c'est pour ça que l'on n'a pas mis <span class="code">:id => false</span> après le <span class="code">create_table</span>.
</p>
<h3 id='adapter-les-modeles-6'>Adapter les modèles</h3>
<p>
  Maintenant que la table de jointure est crée, il faut renseigner dans les modèles la façon dont ils sont liés entre eux.
</p>
<pre class='prettyprint linenums'># app/models/doctor.rb
Class Doctor &lt; ActiveRecord::Base
  has_many :appointments
  has_many :patients,    :through =&gt; :appointments
end
# app/models/patient.rb
Class Patient &lt; ActiveRecord::Base
  has_many :appointments
  has_many :doctors,     :through =&gt; :appointments
end
# app/models/appointment.rb
Class Appointment &lt; ActiveRecord::Base
  belongs_to :doctor
  belongs_to :patient
end</pre>
<p>
  Comme vous le voyez, on n'utilise plus <span class="code">has_and_belong_to_many</span>. Maintenant, les docteurs ont plusieurs patients et vice-versa <b>à travers</b> la table Appointment.
  Dans cette table seront stockées les informations qui lient les docteurs aux patients.
  C'est pour cela que l'on utilise le mot clé <span class="code">:through</span>. On indique à Rails que s'il veut trouver les patients liés à un docteur il devra passer par la table Appointments pour les trouver.
</p>
<h2 id='comment-utiliser-ces-relations-dans-les-controleurs-7'>Comment utiliser ces relations dans les contrôleurs</h2>
<h3 id='manipuler-les-associations-ici-des-«appointments»-8'>Manipuler les associations (ici des «appointments»)</h3>
<p>
  Plusieurs moyens s'offre à vous pour créer un <code>Appointment</code> qui lie un <code>Doctor</code> et un <code>Patient</code>.
  En voici un exemple&nbsp;:
</p>
<pre class='prettyprint linenums'># @patient et @doctor contiennent une instance d'un docteur et d'un patient
Appointment.create(:doctor =&gt; @doctor, :patient =&gt; @patient, :appointment_date =&gt; Date.tomorrow)</pre>
<p>
  Vous pouvez également créer une association sans spécifier tous les champs, juste en ajoutant un nouveau patient à la liste des docteurs ou vice-versa :
</p>
<pre class='prettyprint linenums'>@doctor.patients &lt;&lt; @patient
# Ou bien 
@patient.doctors &lt;&lt; @doctor</pre>
<p>
  Cela créera automatiquement un Appointment avec les bonnes valeurs pour <span class="code">doctor_id</span> et <span class="code">patient_id</span>, mais tous les autres attributs (ici, la date) seront fixés à null.
</p>
<p>
  Si vous voulez réaffecter toute la liste des patients ou des docteurs vous pouvez faire comme suit :
</p>
<pre class='prettyprint linenums'>@doctor.patients = @new_array_of_patients</pre>
<p>
  Ici plusieurs choses sont à noter :
</p>
<ul>
  <li>des appointments sont créés pour lier les nouveaux patients au docteur ;</li>
  <li>si des patients de la nouvelle liste étaient déjà présents, leurs appointments ne seront pas supprimés ;</li>
  <li>les appointments de tous les patients qui ne sont pas dans la nouvelle liste seront supprimés.</li>
</ul>
<h3 id='supprimer-une-association-9'>Supprimer une association</h3>
<p>
  Comme je l'ai dit précédemment, en réaffectant de nouveaux patients à un docteur, ses anciennes associations seront automatiquement supprimées.
  Si vous voulez supprimer une association en particulier, vous pouvez simplement faire comme suit&nbsp;:
</p>
<pre class='prettyprint linenums'># On supprime tous les appointments qui existent entre @doctor et @patient
@doctor.patients.delete(@patient)
# Ou bien
@patient.doctors.delete(@doctor)
# Ou encore, pour supprimer les appointments qui ont une date antérieur à aujourd'hui
@patient.appointments.where(&quot;appointment_date &lt; ?&quot;, Date.today).delete</pre>
<h3 id='les-helpers-rails-10'>Les helpers Rails</h3>
<p>
  Rails crée également un tas de <code>helpers</code> qui peuvent être très sympa et que vous trouverez dans l'<a target='_blank' href='http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html'>API Rails</a>. Voici un un avant goût :
</p>
<pre class='prettyprint linenums'>@doctor.patient_ids
@doctor.patients.delete_all
@doctor.patients.size
# Etc.</pre>
<h2 id='egalement-utile-pour-creer-des-«raccourcis»-11'>Également utile pour créer des «raccourcis»</h2>
<p>
  Vous pouvez vous servir des <span class="code">has_many :through</span> pour vous faire des raccourcis. Je m'explique.
  Supposez qu'un document à plusieurs sections et que les sections ont plusieurs paragraphes comme le montre le schéma suivant&nbsp;:
</p>
<img alt='Représentation schématique de la relation Many to Many' src='http://ontherailsagain.com/article_images/Associations_Many-to-Many_avancees/Document.png' title="Schéma de l'association Many to Many" />
<p>Il peut arriver que vous ayez besoin d'accéder à tous les paragraphes d'un document. Pour faire cela, vous pouvez par exemple définir vos relations comme suit&nbsp;:</p>
<pre class='prettyprint linenums'># app/models/document.rb
class Document &lt; ActiveRecord::Base
  has_many :sections
  has_many :paragraphs, :through =&gt; :sections
end
# app/models/section.rb
class Section &lt; ActiveRecord::Base
  belongs_to :document
  has_many :paragraphs
end
# app/models/paragraph.rb
class Paragraph &lt; ActiveRecord::Base
  belongs_to :section
end</pre>
<p>
  Et donc pour accéder à tous les paragraphes d'un document il suffit de faire&nbsp;:
</p>
<pre class='prettyprint linenums'>@document.paragraphs</pre>
<p>
  Voilà, vous devriez avoir toutes les clés pour mettre en place vos relations. Si vous avez des questions ou des améliorations à proposer n'hésitez pas à laisser un commentaire !
</p>
<h2 id='references-12'>Références</h2>
<ul>
  <li>
    <a href='http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association' target='_blank'>Guide rails sur les associations</a>
  </li>
  <li>
    <a href='http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html' target='_blank'>API Rails</a>
    sur les associations
  </li>
</ul>
]]></content:encoded><description>Maintenant que nous avons abordé les relations Many-to-Many simples, voyons comment mettre en oeuvre les relations Many-to-Many avancées (ou has_many :through).Cette relation permet de stocker des données relatives à l'association qui lie deux modèles.</description><feedburner:origLink>http://ontherailsagain.com/articles/les-associations-many-to-many-avancees</feedburner:origLink></item><item><title>Les associations Many-to-Many</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/QxxM_7oq4WE/les-associations-many-to-many</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nima</dc:creator><pubDate>Mon, 10 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/les-associations-many-to-many</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='require'>
  Pré-requis :
  <ul>
    <li>avoir des bases en SQL (table, clé primaire, clé étrangère ;</li>
    <li>
      avoir vu les associations
      <a href='http://ontherailsagain.com/articles/Les-associations-one-to-many' target='_blank'>One-to-Many.</a>
    </li>
  </ul>
</div>
<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>comprendre une relation Many-to-Many ;</li>
    <li>créer une relation Many-to-Many avec Rails.</li>
  </ul>
</div>
<h2 id='presentation-du-probleme-1'>Présentation du problème</h2>
<p>
  Lorsque l'on conçoit une application on tombe souvent sur un problème simple : un objet A peut <b>avoir plusieurs</b> objets B et un objet B
  peut <b>avoir plusieurs</b> objets A... Bon, tout ceci n'est pas très clair, mais quand on l'illustre par un exemple ça le devient.
</p>
<p>
  Prenons un exemple très courant : <b>Elèves - Cours</b>.
  Un élève peut <strong>avoir plusieurs</strong> cours et <strong>appartenir à plusieurs</strong> cours.
  Ou encore avec un autre exemple : <b>Articles - Tags</b>. Un article peut <strong>avoir</strong> et peut <strong>appartenir à plusieurs</strong>
  tags. Effectivement un tag n'est pas unique, ce n'est pas parce qu'un article <b>a</b>
  le tag Ruby qu'aucun autre article ne pourra avoir ce même tag.
</p>
<h2 id='en-theorie-2'>En théorie</h2>
<p>
  Cette association ressemble à une double association One-to-Many, mais le problème est : « Où mettre la/les clé(s) étrangère(s) pour connaître les associations entre les objets&nbsp;?&nbsp;»
</p>
<p>
  Pour ça,  il faut créer ce que l'on appelle une table de jointure (ou d'association) pour stocker les couples de clés étrangères appartenant aux deux modèles concernés.
  Il est important de noter que cette table d'association ne sera constituée uniquement de deux colonnes qui contiendront des clés étrangères. En d'autres termes, cette table ne doit pas contenir de clé primaire.
</p>
<h2 id='en-pratique-3'>En pratique</h2>
<p>Avant de continuer, voilà une représentation de la relation des modèles entre eux.</p>
<img alt='Représentation schématique de la relation Many to Many' src='http://ontherailsagain.com/article_images/Associations_Many-to-Many/Many-to-Many.png' title="Schéma de l'association Many to Many" />
<h3 id='creation-des-modeles-4'>Création des modèles</h3>
<p>
  Prenons l'exemple des <b>Articles</b> et des <b>Tags</b>.
  Nous avons donc deux modèles, le modèle <code>Article</code> et le modèle <code>Tag</code> et nous voulons pouvoir associer plusieurs tags à un article mais également plusieurs articles au même tag.
  Commençons par créer les deux modèles à l'aide des scaffolds :
</p>
<pre class='prettyprint linenums'>$ rails generate scaffold Article title:string content:text
$ rails generate scaffold Tag name:string</pre>
<h3 id='creation-de-la-migration-5'>Création de la migration</h3>
<p>
  Bon, comme vous vous en doutez, la table de jointure ne vas pas se créer toute seule. Pour la créer nous allons passer par une migration (hors de question de la créer à la « main » !)
</p>
<p class='notice'>
  Les migrations sont un moyen pratique de modifier la base de données de façon structurée et organisée. Elles décrivent des actions à effectuer comme créer une table, ajouter/supprimer une colonne à une table, etc. Elles permettent également de garder une trace de toutes les modifications effectuées sur la base de données.
</p>
<h4 id='convention-de-nommage-6'>Convention de nommage</h4>
<p>
  Mais avant de faire ça, comme le principe de Rails est « Convention Over Configuration », il faut bien comprendre comment nommer cette table de jointure.
  Voici les conventions à respecter pour le nom de cette table :
</p>
<ul>
  <li>nom_modèle_1 + _ + nom_modèle_2 ;</li>
  <li>Les deux noms de tables doivent être au pluriel ;</li>
  <li>Les noms des tables sont ordonnés alphabétiquement. Donc <b>Articles</b> vient avant <b>Tags</b>.</li>
</ul>
<p>
  Dans notre cas, le nom sera donc : <code>articles_tags</code>.
  Article en premier car il est alphabétiquement avant Tag, et les deux noms au pluriel.
  Si le nom d'un de vos modèles est en plusieurs mots, il suffit de remplacer les espaces par des « _ ». <br /> Exemple : Le nom d'une table de jointure pour un modèle BlogPost et un modèle Category serait <code>blog_posts_categories</code>.
</p>
<p class='notice'>
  <em>Pour les anglophobes :</em>
  faites bien attention au pluriel anglais pour les mots qui se finissent en « y ». « One category but two categories ! »
</p>
<h4 id='le-fichier-migration-7'>Le fichier migration</h4>
<p>
  Maintenant que nous savons comment nommer cette table et que l'on sait qu'elle ne doit pas avoir de clé primaire nous pouvons créer la migration.
  Tâchez de donner un nom explicite à celle-ci (celui du fichier qui apparaitra dans le dossier db/migrations), cela pourrait vous servir à l'avenir si vous avez besoin de revenir en arrière.
</p>
<pre class='prettyprint linenums'>$ rails generate migration CreateArticlesTagsJoinTable</pre>
<p>
  Il faut maintenant éditer cette migration pour y ajouter l'instruction de création de la table avec le bon nom (comme nous avons vu ci-dessus).
</p>
<pre class='prettyprint linenums'># db/migrations/20111009221942_create_articles_tags_join_table
class CreateArticlesTagsJoinTable &lt; ActiveRecord::Migration
  def self.up
    create_table :articles_tags, :id =&gt; false do |t|
      t.references :article, :tag # Pour créer les clés etrangères
    end
    add_index :articles_tags, [:article_id, :tag_id] # Optionnel
  end
  def self.down
    drop_table :articles_tags
  end
end</pre>
<p>
  Comme on le voit, il faut absolument préciser <span class="code">:id => false</span> pour qu'aucune clé primaire ne soit créée.
  L'instruction <span class="code">add_index</span> est optionnelle mais permet d'accélérer les recherches en base de données.
</p>
<p>Ensuite, pour exécuter la migration il vous suffit d'éxécuter la commande suivante :</p>
<pre class='prettyprint linenums'>rake db:migrate</pre>
<h3 id='adaptation-des-modeles-8'>Adaptation des modèles</h3>
<p>
  Il ne reste plus qu'à spécifier aux modèles les associations et le tour est joué ! Traduction&nbsp;: dire aux Articles qu'ils
  <em>ont et appartiennent (has_and_belongs) à plusieurs (to_many)</em>
  Tags. Et vice-versa !
</p>
<pre class='prettyprint linenums'># app/models/article.rb
class Article &lt; ActiveRecord::Base
  has_and_belongs_to_many :tags
end
# app/models/tag.rb
class Tag &lt; ActiveRecord::Base
  has_and_belongs_to_many :articles
end</pre>
<h2 id='utilisation-dans-les-vues-9'>Utilisation dans les vues</h2>
<p>
  Vous pouvez être amené à vous demander comment gérer ces dépendances dans un formulaire. Par exemple, lors de la création d'un article je voudrais pouvoir choisir tous les tags qui lui seront associés.
  Voilà une méthode pour faire ça&nbsp;:
</p>
<pre class='prettyprint linenums'># app/views/articles/_form.html.erb
&lt;%= form_for @article do |f| %&gt;
  &lt;label&gt;Title: &lt;%= f.text_field :title %&gt; &lt;/label&gt;
  &lt;% Tag.all.each do |tag| %&gt;
    &lt;label&gt;&lt;%= tag.name %&gt;
      &lt;%= check_box_tag &quot;article[tag_ids][]&quot;, tag.id, @article.tags.include?(tag) %&gt;
    &lt;/label&gt;
  &lt;% end %&gt;
  &lt;%= f.submit %&gt;
&lt;% end %&gt;</pre>
<p>
  Ce qui se passe ici c'est que lors de la création d'un article on va chercher tous les tags existant en base de données (<span class="code">Tag.all</span>) et on affiche une checkbox pour chacun de ces tags. Ce formulaire servant également pour l'édition, on regarde si l'article n'a pas déjà ce tag
  (<span class="code">@article.tags.include?(tag)</span>) et si oui, la checkbox sera cochée.
</p>
<p>
  De plus, il n'y a rien a changer du côté du contrôleur, l'affectation des tags à l'article se fera automatiquement grâce au nom de l'input qui est <span class="code">article[tag_ids][]</span>. En effet, dans la methode create du contrôleur de l'article on retrouve&nbsp;:
</p>
<pre class='prettyprint linenums'># app/controllers/articles_controller.rb
def create
  @article = Article.new(params[:article])
  ...
end</pre>
<p>
  L'article qui va être mis en base de donnée est créé à partir des paramètres qui sont stockés dans le tableau article lors de l'envoi du formulaire.
</p>
<h2 id='utilisation-dans-les-controleurs-10'>Utilisation dans les contrôleurs</h2>
<p>
  Une fois toute la partie base de données et modèle mis en place, Rails permet d'accéder aux objets entre eux très simplement. Par exemple, pour accéder à tous les tags d'un article on peut faire&nbsp;:
</p>
<pre class='prettyprint linenums'>@article.tags # Renvoie un tableau contenant tous les tags de @article</pre>
<p>Pour ce qui est de l'affectation il y a deux possibilités&nbsp;:</p>
<pre class='prettyprint linenums'>@article.tags &lt;&lt; Tag.first # On ajoute au tags déjà existant
@article.tags = Tag.first  # On remplace les tags déjà existant</pre>
<p>
  Si vous utilisez l'opérateur <span class="code">=</span>, il faut bien garder en tête que tous les tags que possédait l'article seront remplacés par la nouvelle affectation.
  Au contraire, si vous utilisez l'opérateur <span class="code"><<</span>, le tag sera ajouté aux tags déjà existant.
</p>
<h2 id='references-11'>Références</h2>
<ul>
  <li>
    <a href='http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association' target='_blank'>Guide rails sur les associations</a>
  </li>
  <li>
    <a href='http://guides.rubyonrails.org/migrations.html' target='_blank'>Guide rails sur les migrations</a>
  </li>
</ul>
<p>
  Voilà pour les associations Many-to-Many. Je posterai un article sur les associations Many-to-Many avancées (<span class="code">has_many :through</span>) dans les jours à venir. Si vous avez des questions ou des améliorations à proposer n'hésitez pas à laisser un commentaire !
</p>
]]></content:encoded><description>Arpès avoir vu les associations One-to-Many, il est temps de s'attaquer aux associations Many-to-Many qui sont fréquemment utilisées mais qui ne sont pas forcément évidentes à implémenter dans une application Rails au début.</description><feedburner:origLink>http://ontherailsagain.com/articles/les-associations-many-to-many</feedburner:origLink></item><item><title>Comprendre la structure d'une application Rails</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/yFzCIH_LyZ8/comprendre-la-structure-d-une-application-rails</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nicolas</dc:creator><pubDate>Sun, 09 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/comprendre-la-structure-d-une-application-rails</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>Comprendre l'intérêt de chaque fichier et de chaque dossier.</li>
  </ul>
</div>
<p>Lorsque que l'on veut se lancer dans Ruby On Rails, il peut arriver que l'on soit un peu perturbé, voire découragé par la quantité de fichiers et de dossiers qui sont générés après avoir tapé la commande suivante :</p>
<pre class='prettyprint linenums'>$ rails new mon_application</pre>
<p>En effet, après avoir tapé cette commande, on obtient un dossier se nommant <i>mon_application</i> qui contient une dizaine de sous-dossiers, qui contiennent eux-mêmes d'autres dossiers…</p>
<p>A quoi servent tous ces dossiers ? Où dois-je mettre mon code ?</p>
<p>Si l'on comprend ce que chaque dossier contient, leurs intérêts et ceux dans lesquels on doit travailler, les choses sont de suite beaucoup moins repoussantes. Analysons rapidement chaque fichier et chaque dossier.</p>
<h2 id='les-plus-importants-1'>Les plus importants</h2>
<h3 id='le-dossier-app-le-dossier-ou-l-on-passe-90-de-son-temps-2'>Le dossier app, le dossier où l'on passe 90% de son temps</h3>
<p>Ce dossier est certainement celui dans lequel vous allez passer le plus de temps. En effet c'est dans ce dossier que se trouvera le coeur de votre application. D'ailleurs lorsque l'on ouvre ce dossier, on voit ceux structurant l'architecture MVC, avec les dossiers <i>models</i>, <i>controllers</i> et <i>views</i>. On trouve également un dossier <i>helpers</i> où l'on mettra des fichiers qui contiennent des méthodes utiles pour nos vues et nos contrôleurs.</p>
<p class='warning'>Il est important de respecter l'architecture MVC et de mettre les bons bouts de code au bon endroit, et donc par exemple de faire attention à ne pas mettre une méthode qui correspond au modèle dans le controleur.</p>
<p>Le dossier <i>app</i> contient également un dossier <i>assets</i> qui contient lui-même les dossiers <i>javascripts</i>, <i>stylesheets</i> et <i>images</i> qui eux-mêmes contiennent respectivement les fichiers Javascripts, les fichiers CSS et les images.</p>
<p class='notice'>Dans les versions de Rails inférieur à 3.1, les dossiers <i>stylesheets</i>, <i>javascripts</i> et <i>images</i> sont dans le dossier <i>public</i>.</p>
<h3 id='le-dossier-config-3'>Le dossier config</h3>
<p>Ce dossier contient comme son nom l'indique tout ce qui correspond à la configuration de l'application. Notamment la configuration de la base de données se fait dans le fichier <i>database.yml</i> et le fichier <i>routes.rb</i> permet de définir les différentes parties de l'application pointées par les URLs. On trouve également un dossier <i>initializers</i> qui contiendra du code exécuté lors du lancement de l'application. Le dossier <i>locales</i> lui contient des fichiers qui vont nous être utiles pour l'internationalisation (I18n) de notre application.</p>
<h3 id='le-dossier-db-4'>Le dossier db</h3>
<p>Ce dossier contient tout ce qui concerne la base de données. Il contient les migrations qui sont des fichiers qui permettent de créer, supprimer, ou modifier des tables et ainsi modifier la base de données.</p>
<h3 id='le-dossier-public-5'>Le dossier public</h3>
<p>Ce dossier contient les fichiers statiques et les ressources compilées comme par exemple des CSS générées à partir de fichier sass ou encore les fichiers Javascript compilés à partir des fichiers coffeescripts.</p>
<h3 id='le-fichier-gemfile-6'>Le fichier Gemfile</h3>
<p>
  Le fichier <i>Gemfile</i> est un fichier très pratique permettant de spécifier les </em>gems</em> et toutes les dépendances nécessaires au bon fonctionnement de votre application. Vous trouverez la majeure partie des gems sur
  <a href='http://rubygems.org/'>RubyGem.</a>
</p>
<h3 id='le-dossier-test-7'>Le dossier test</h3>
<p>Ce dossier contient tous les éléments qui vont nous être utiles pour pouvoir tester notre application. C'est donc dans ce dossier que l'on va mettre tout notre code de test qui nous permettra de vérifier que chacune de nos classes et chacune de nos méthodes effectuent bien le travail attendu.</p>
<p class='notice'>Même si les tests peuvent paraître inutiles et qu'il n'est pas nécessaire d'apprendre à en faire dès le début de notre apprentissage, il est important de noter qu'ils sont indispensables afin de produire une application fiable et de qualité.</p>
<h2 id='les-dossiers-et-fichiers-que-l-on-ne-touche-pas-souvent-8'>Les dossiers et fichiers que l'on ne touche pas souvent</h2>
<h3 id='le-fichier-config-ru-9'>Le fichier config.ru</h3>
<p>Ce fichier de configuration est utilisé par les serveurs Rack pour démarrer votre application.</p>
<h3 id='le-dossier-doc-10'>Le dossier doc</h3>
<p>Ce dossier contient toute le documentation concernant notre application, notamment c'est dans ce dossier que l'on peut stocker nos todos listes ou différentes notes au sujet de notre application.</p>
<h3 id='le-dossier-log-11'>Le dossier log</h3>
<p>Ce dossier contient tous les logs de notre application, cela peut être utile pour savoir ce qu'il se passe dans notre application, puisqu'il contient le détail de chaque action éffectuée par notre application. Par exemple quand on accède à une liste d'éléments contenus dans la base de données, on peut voir la requête SQL effectuée pour récupérer ces données.</p>
<h3 id='le-fichier-readme-12'>Le fichier README</h3>
<p>Dans ce fichier nous pouvons écrire les informations que l'on veut communiquer aux personnes récupérant le code source de notre application. Par exemple, on peut indiquer ce que fait l'application, quelles sont les commandes à éffectuer afin de pouvoir l'exécuter, comment la configurer, etc…</p>
<h3 id='le-dossier-script-13'>Le dossier script</h3>
<p>Ce dossier contient initialement le script rails qui permet par exemple de démarrer notre application et de générer des fichiers comme des modèles ou des contrôleurs. Il peut également contenir d'autres scripts que l'on veut ajouter pour déployer ou lancer notre application.</p>
<h3 id='le-dossier-tmp-14'>Le dossier tmp</h3>
<p>Ce dossier contient tous les éléments temporaires nécessaires à notre application, mais nous n'avons pas à nous en préoccuper.</p>
<h3 id='le-dossier-vendor-15'>Le dossier vendor</h3>
<p>Ce dossier est destiné au code complémentaire de tierces parties. Dans une application Rails typique, cela comprend des gems Ruby, le code source de Rails (s’il est installé dans le projet) et les plugins contenant des fonctionnalités additionnelles packagées.</p>
<h3 id='le-fichier-rakefile-16'>Le fichier Rakefile</h3>
<p>Ce fichier localise et charge les tâches qui peuvent être utilisées depuis la ligne de commande. Là encore on n'a pas vraiment besoin de s'en préoccuper.</p>
<p>Voilà pour l'ensemble des fichiers et dossiers. Si vous avez des questions ou améliorations à proposer n'hésitez pas à laisser un commentaire !</p>
<h2 id='references-17'>Références</h2>
<ul>
  <li>
    <a href='http://guides.rubyonrails.org/getting_started.html' target='_blank'>Rails guide : Getting Started</a>
  </li>
  <li>
    <a href='http://railsdebutant.org/fr_guides/getting_started.html' target='_blank'>Rails guide : Getting Started (fr)</a>
  </li>
</ul>
]]></content:encoded><description>La structure d'une application Ruby On Rails peut dérouter du fait du nombre de fichiers et dossiers qu'elle contient. Cet article présente rapidement  l'intérêt de chacun de ces fichiers et dossiers afin de comprendre cette structure.</description><feedburner:origLink>http://ontherailsagain.com/articles/comprendre-la-structure-d-une-application-rails</feedburner:origLink></item><item><title>Les associations One-to-Many</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/GkdPz4jhe0g/les-associations-one-to-many</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nima</dc:creator><pubDate>Sun, 02 Oct 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/les-associations-one-to-many</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div class='see'>
  Ce que nous allons voir :
  <ul>
    <li>comprendre ce qu'est une association <a href="http://ontherailsagain.com/articles/les-associations-one-to-many" target="_blank">One-to-Many</a> ;</li>
    <li>mettre en place une association <a href="http://ontherailsagain.com/articles/les-associations-one-to-many" target="_blank">One-to-Many</a> avec Rails.</li>
  </ul>
</div>
<h2 id='presentation-du-probleme-1'>Présentation du problème</h2>
<p>
  Le problème est relativement simple, le but d'une association est de pouvoir recréer des relations d'appartenance sur le plan informatique.
  Par exemple, comment représenter le fait qu'un écrivain possède plusieurs livres ? Ce problème est assez courant dans les applications et Rails nous permet de mettre ça en place assez facilement.
</p>
<h2 id='un-exemple-concret-2'>Un exemple concret</h2>
<p>
  Pour bien comprendre comment cela marche, on va prendre un exemple concret.
  Pour reprendre l'exemple cité ci-dessus, nous avons donc des écrivains qui écrivent des livres. On a donc une application avec des écrivains et des livres et on veut relier ces deux entités ensemble par une relation d'appartenance.
  En gros :
</p>
<ul>
  <li>un écrivain a plusieurs livres ;</li>
  <li>un livre n'appartient qu'à un écrivain.</li>
</ul>
<h2 id='en-theorie-3'>En théorie</h2>
<p>
  En "théorie" pour résoudre ce problème, il suffit que chaque livre ait une référence vers son écrivain.
  Pour être un peu plus théorique, on peut visualiser la relation par un arbre à deux niveaux, l'écrivain étant une racine et tous ses livres étant des feuilles.
  Dans ce cas-là, toutes les feuilles (livres) ont une référence vers la racine (l'écrivain).
  En terme de base de données cela donne quelque chose comme ça :
</p>
<pre class='prettyprint linenums'>Writer - id:integer  name:string
Book   - id:integer  title:string writer_id:integer(foreign_key)</pre>
<p>
  Comme on le voit là, le livre a une référence vers son écrivain et cette référence est une clé étrangère vers la table <code>Writer</code>.
</p>
<h2 id='en-pratique-4'>En pratique</h2>
<p>Avant de continuer, voilà une représentation de la relation des modèles entre eux.</p>
<img alt='Représentation schématique de la relation One to Many' src='http://ontherailsagain.com/article_images/Associations_One-to-Many/One-to-Many.png' title="Schéma de l'association One to Many" />
<h3 id='preparer-la-base-de-donnees-5'>Préparer la base de données</h3>
<p>
  Bon, la vraie question maintenant c'est : "Comment on fait avec Rails ?"
  Eh bien comme on va le voir, ce n'est pas bien compliqué !
  On crée tout d'abord nos modèles comme suit :
</p>
<pre class='prettyprint linenums'>$ rails generate scaffold Writer name:string 
$ rails generate scaffold Book   title:string writer_id:integer
$ rake db:migrate</pre>
<p>
  Ici on peut noter plusieurs choses. Premièrement, les IDs des modèles sont générés automatiquement, pas besoin de spécifier quoique se soit.
  Mais surtout, le fait de nommer la référence écrivain <span class="code">writer_id</span>
  n'est pas anodin. En mettant bien le nom de la table de référence (en minuscule et au singulier) suivit de <span class="code">_id</span>
  on indique à Rails que c'est une clé étrangère qui correspond à l'identifiant de l'objet <code>Writer</code>.
</p>
<h3 id='mettre-les-choses-en-place-dans-les-modeles-6'>Mettre les choses en place dans les modèles</h3>
<p>
  Bon, évidemment ce n'est pas tout, mais c'est presque fini ! Il suffit maintenant de spécifier qui appartient à quoi dans les modèles et le tour est joué !
  Comme on l'a dit plus haut, un écrivain  <strong>possède plusieurs (has many)</strong>
  livres. Ou encore, un livre <strong>appartient à (belongs to)</strong>
  un écrivain. Je mets en avant ces mots clés, car c'est grâce à ces derniers qu'on va décrire à Rails notre relation. En pratique ça donne :
</p>
<pre class='prettyprint linenums'># app/models/writer.rb
class Writer &lt; ActiveRecord::Base
  has_many :books
end
# app/models/book.rb
class Book &lt; ActiveRecord::Base
  belongs_to :writer
end</pre>
<p>
  Il est important de noter ici le pluriel et le singulier des mots. Un écrivain possède DES livres &rarr; Je mets un pluriel. Un livre appartient à UN écrivain &rarr; singulier.
  Si vous avez oublié la syntaxe, voilà un petit mémo : c'est logique.
  Ah et, j'oubliais de dire que... Voilà, c'est tout.
</p>
<h2 id='utilisation-dans-le-code-7'>Utilisation dans le code</h2>
<p>
  Alors, évidemment, le fait de faire ça ne vous change pas vos vues ni vos contrôleurs automatiquement. Si vous cherchez la simplicité il y a des gems comme InheritedResource qui existent pour vous simplifier la vie dans les contrôleurs mais si vous débutez je vous le déconseille.
</p>
<h3 id='dans-le-controleur-8'>Dans le contrôleur</h3>
<p>
  Un des endroits ou l'affectation d'un écrivain à un livre peut être utile est dans le contrôleur <code>books_controller</code>.
  Si vous voulez par exemple affecter toujours le même écrivain à tous les livres, vous pouvez dans, la méthode <code>create</code>
  du contrôleur <code>books_controller</code>,
  spécifier l'id de l'écrivain comme suit :
</p>
<pre class='prettyprint linenums'># app/controllers/book_controller.rb
def create
  super_writer = Writer.first
  @book = Book.new(params[:book])
  @comment.writer = super_writer
  # Ou 
  @comment.writer_id = super_writer.id
  ...
end</pre>
<p>
  Comme vous le voyez, vous avez plusieurs façons possibles d'associer un écrivain à un livre. Si au contraire vous voulez attribuer des livres à un écrivain, c'est quasiment pareil :
</p>
<pre class='prettyprint linenums'>book_list = Book.all
@writer.books = book_list
# Ou alors
@writer.books &lt;&lt; Book.last</pre>
<p>
  Il y a deux façons de faire cette affectation. <span class="code">@writer.books</span> (à condition que <span class="code">@writer</span>
  soit définit avant) va vous renvoyer un tableau de livres. Vous pouvez donc soit, écraser ce tableau en utilisant l'opérateur <span class="code">=</span>,
  soit ajouter des livres à cette liste avec l'opérateur <span class="code">&lt;&lt;</span>.
</p>
<h3 id='dans-la-vue-9'>Dans la vue</h3>
<p>
  Un autre cas de figure est possible : vous voulez pouvoir choisir l'écrivain à la création d'un livre. Dans ce cas, on voudrait par exemple que dans le formulaire de création d'un livre
  on ait la liste de tous les écrivains du site et qu'il suffisse de sélectionner l'écrivain voulut pour l'associer au livre. Voilà une façon de faire :
</p>
<pre class='prettyprint linenums'># app/views/books/_form.html.erb
&lt;%= form_for(@book) do |f| %&gt;
  &lt;div class='field'&gt;
    &lt;%= f.label :title, &quot;Titre&quot; %&gt;&lt;br /&gt;
    &lt;%= f.text_field :title %&gt;
  &lt;/div&gt;
  &lt;div class='field'&gt;  
    &lt;%= collection_select(:book, :writer_id, Writer.find(:all), :id, :name) %&gt;
  &lt;/div&gt;
  &lt;div class='actions'&gt;
    &lt;%= f.submit 'Créer le livre'%&gt;
  &lt;/div&gt;
&lt;% end %&gt;</pre>
<p>
  Bon, tout ceci mérite quelques explications.
  En fait, la fonction <code>collection_select</code>
  est un helper qui va générer du code HTML en fonction de ce qu'on lui passe. Vous pouvez avoir la doc
  <a href='http://ap.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#M000455' target='_blank'>ici</a>
  si ça vous intéresse.
  Sinon, ce n'est pas bien compliqué. La fonction prend 5 paramètres obligatoires et deux optionnels. Voyons les dans l'ordre :
</p>
<dl>
  <dt>Object :</dt>
  <dd>
    Le nom de l'objet du formulaire. Ici <span class="code">:book</span> car on crée un livre.
  </dd>
  <dt>Method :</dt>
  <dd>
    La méthode employée pour récupérer la valeur du select. Ici, la valeur correspond à l'id de l'écrivain, donc <span class="code">:writer_id</span>.
  </dd>
  <dt>Collection :</dt>
  <dd>
    la collection d'objet qu'on lui passe. On veut lui passer tous les écrivains, donc <span class="code">Writer.find(:all)</span> ou <span class="code">Writer.all</span>.
  </dd>
  <dt>Value_method :</dt>
  <dd>
    la méthode qui va être appelée sur chaque élément de la collection pour récupérer la valeur voulut. Ici on veut l'id de l'écrivain <span class="code">(writer.id)</span> donc la méthode est <span class="code">:id</span>.
  </dd>
  <dt>Text_method :</dt>
  <dd>
    La méthode qui va être appelée sur chaque élément de la collection pour afficher la valeur dans la select box. Ici on veut le nom de l'écrivain donc :name.
    Si l'écrivain avait deux attributs <span class="code">:firstname </span> et <span class="code">:lastname</span>
    on aurait pu faire une méthode simple dans le modèle pour récupérer le nom sous la forme <span class="code">"#{first_name} #{last_name}"</span>. Dans ce cas, il aurait donc fallu mettre le nom de cette méthode plutôt que <span class="code">:name</span>.
  </dd>
  <dt>Options :</dt>
  <dd>
    Des options comme <span class="code">{:include_blank &rarr; true} </span> pour mettre une première valeur null ou <span class="code">{:prompt => "Choisir un écrivain"}</span> pour mettre un texte à la première valeur.
  </dd>
  <dt>HTML_options :</dt>
  <dd>
    Les options html que peut prendre le tag select, comme <span class="code">{:class => "my_select_box"}</span>, etc…
  </dd>
</dl>
<p>
  Voilà pour les associations One-to_Many. Si vous avez des questions n'hésitez pas à laisser un commentaire !
</p>
<h2 id='references-10'>Références</h2>
<ul>
  <li>
    <a href='http://ap.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#M000455' target='_blank'>API Rails</a>
  </li>
  <li>
    <a href='http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association' target='_blank'>Guide rails sur les associations</a>
  </li>
</ul>
]]></content:encoded><description>Les associations font partie des choses les plus basiques et les plus importantes à maitriser lors de la création d'une application web. Après une petite revue du problème, nous allons voir comment mettre en place ces relations avec Rails.</description><feedburner:origLink>http://ontherailsagain.com/articles/les-associations-one-to-many</feedburner:origLink></item><item><title>Avant de commencer avec Ruby on Rails</title><link>http://feedproxy.google.com/~r/OnTheRailsAgain/~3/wCOaQ6jUgqs/avant-de-commencer-avec-ruby-on-rails</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nicolas et Nima</dc:creator><pubDate>Tue, 27 Sep 2011 17:00:00 PDT</pubDate><guid isPermaLink="false">http://ontherailsagain.com/articles/avant-de-commencer-avec-ruby-on-rails</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>
  A l'heure où nous écrivons cet article et lançons ce blog nous sommes à la version 3 de Rails (la sortie officielle date du
  <a target='_blank' href="http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done">29 Août 2010</a>)
  donc faites attention lors de vos différentes recherches sur internet, pensez bien à regarder les versions utilisées !
</p>
<h2 id='ruby-et-les-gems-1'>Ruby et les Gems</h2>
<h3 id='ruby-2'>Ruby</h3>
<p>
  Le framework Ruby On Rails étant écrit en Ruby, connaitre quelques bases du langage pourra toujours aider.
  Pas de panique ! Pas besoin d'être un expert en Ruby pour savoir faire du Rails, mais cela vous aidera dans l'apprentissage de ce framework !
</p>
<ul>
  <li>
    <a href='http://www.ruby-lang.org/en/' target='_blank'>Site officiel</a>
    ;
  </li>
  <li>
    <a href='http://www.ruby-lang.org/fr/documentation/quickstart/' target='_blank'>Le quickstart</a>
    du site officiel ;
  </li>
  <li>
    <a href='http://tryruby.org/' target='_blank'>TryRuby.org</a>
    - un petit interpreteur interactif.
  </li>
  <li>
    <a href='http://rubymonk.com/' target='_blank'>RubyMonk</a>
    - un site interactif pour apprendre le ruby.
  </li>
</ul>
<h3 id='les-gems-3'>Les Gems</h3>
<p>
  Les Gems sont comme des petits modules (ce sont des applications et bibliothèques Ruby empaquetées) que l'on peut ajouter à notre application Rails et qui permettent assez souvent de se simplifier la vie.
  Par exemple des Gems d'authentification existent et permettent de ne pas à avoir à coder tout un système d'authentification.
  Il n'est pas nécessaire de savoir se servir des Gems pour commencer à faire du Rails, mais il est toujours bon de savoir qu'elles existent.
  Voici des liens à connaître où vous pourrez trouver la plupart des Gems&nbsp;:
</p>
<ul>
  <li>
    <a href='http://rubygems.org/' target='_blank'>RubyGems</a>
    ;
  </li>
  <li>
    <a href='https://www.ruby-toolbox.com/' target='_blank'>Ruby Toolbox.</a>
  </li>
</ul>
<h2 id='le-mvc-modele-vue-controleur-4'>Le MVC - Modèle-Vue-Contrôleur</h2>
<p>
  Le MVC est une architecture actuellement très répandue et vous sera également utile pour d'autres projets informatiques donc n'hésitez vraiment pas à vous y attarder ! Le concept n'est pas évident et clair du premier coup d'oeil donc n'hésitez pas à lire plusieurs articles pour mieux comprendre. Quoiqu'il en soit le temps aidera également à la compréhension !
</p>
<p>Mais nous allons tout de même voir un aperçu de ce qu'est l'architecture MVC autour de laquelle Rails est organisé.</p>
<p>Tout d'abord, les avantages de l'architecture MVC sont les suivants :</p>
<ul>
  <li>la séparation de la logique métier de l’interface utilisateur ;</li>
  <li>la limitation naturelle des répétitions (DRY) ;</li>
  <li>l’évidence de l’emplacement des différents types de code pour une maintenance facilitée.</li>
</ul>
<h3 id='les-modeles-5'>Les Modèles</h3>
<p>Un modèle représente l’information, les données d’une application et les règles pour la manipuler. Dans le cas de Rails, les modèles sont d’abord utilisés pour gérer les interactions avec les tables dans une base de données. Le plus souvent une table dans votre base correspond à un modèle dans l’application. L’essentiel de la logique métier de votre application est concentré dans les modèles.</p>
<h3 id='les-vues-6'>Les Vues</h3>
<p>Les vues sont l’interface utilisateur de votre application. En Rails, les vues sont souvent des fichiers HTML contenant du code Ruby intégré et dédié à la présentation des données. Les vues ont la responsabilité de fournir des données au navigateur, ou aux autres outils utilisés pour faire des requêtes à votre application.</p>
<h3 id='les-controleurs-7'>Les Contrôleurs</h3>
<p>Les contrôleurs constituent le lien entre les modèles et les vues. En Rails, les contrôleurs sont responsables du traitement des requêtes entrantes en provenance du navigateur, de l’interrogation des modèles pour obtenir des données, et du passage de ces données aux vues pour leur présentation.</p>
<ul>
  <li>
    <a href='http://fr.wikipedia.org/wiki/Modèle-Vue-Contrôleur' target='_blank'>MVC avec Wikipedia</a>
    ;
  </li>
  <li>
    <a href='http://www.siteduzero.com/tutoriel-3-65541-un-pattern-puissant-le-pattern-mvc.html' target='_blank'>MVC sur le site du zéro.</a>
  </li>
</ul>
<h2 id='rest-representational-state-transfer-8'>REST - Representational State Transfer</h2>
<p>
  REST est un style d'architecture et la vie sera bien plus facile pour vous si vous concevez vos applications Rails comme ceci.
</p>
<ul>
  <li>
    <a href='http://fr.wikipedia.org/wiki/Representational_State_Transfer' target='_blank'>REST avec Wikipedia</a>
    ;
  </li>
  <li>
    <a href='http://www.pompage.net/traduction/comment-j-ai-explique-rest-a-ma-femme' target='_blank'>Comment j'ai expliqué REST à ma femme</a>
    ;
  </li>
  <li>
    <a href='http://www.biologeek.com/rest,traduction,web-semantique/pour-ne-plus-etre-en-rest-comprendre-cette-architecture/' target='_blank'>Pour ne plus être en REST, comprendre cette architecture.</a>
  </li>
  <li>
    <a href='http://www.croes.org/gerald/blog/qu-est-ce-que-rest/447/' target='_blank'>Gerald's Blog - Qu’est-ce que REST ?</a>
  </li>
  <li>
    <a href='http://www.aeon-consulting.fr/2009/07/08/comprendre-rest-partie-1-ressource/' target='_blank'>Aeon Blog - Comprendre REST</a>
  </li>
</ul>
<h2 id='references-bibliographique-9'>Références bibliographique</h2>
<p>
  Vous aimez la lecture ? Vous préférez apprendre avec un bon livre ? Voilà quelques références qui pourraient vous intéresser !
</p>
<ul>
  <li>
    <a href='http://pragprog.com/book/rails4/agile-web-development-with-rails' target='_blank'>Agile Web Development with Rails (4th edition)</a>
    En anglais, certes, mais un très bon livre pour débuter. Des notions de développement agiles sont également enseignées avec ce livre !
  </li>
</ul>
<h2 id='allez-voir-ailleurs-10'>Allez voir ailleurs !</h2>
<p>
  Nous vous incitons fortement à aller voir les articles et les tutoriels des autres ! D'ailleurs si vous êtes féru en anglais n'hésitez pas à aller du côté de la communauté anglaise qui possède également beaucoup de ressources.
  Un tas de personnes font des articles et des tutoriels avec un autre point de vue que le nôtre, une façon de penser qui se rapproche peut être plus de la vôtre.
  Voilà une liste non exhaustive, évidemment :
</p>
<ul>
  <li>
    Les
    <a href='http://guides.rubyonrails.org/' target='_blank'>RailsGuides.</a>
    Nous ne pouvons que le conseiller très très fortement. Long et en anglais, mais remplis de la plupart des informations que vous cherchez et chercherez&nbsp;!
  </li>
  <li>
    Les
    <a href='http://railsdebutant.org/fr_guides/' target='_blank'>Guides Rails</a>
    La même chose mais en français ! Tout n'est pas traduit, mais vous trouverez une partie des guides en français. (La première page est en anglais mais les guides sont bien en français !)
    Ces traductions correspondent au
    <a href='https://github.com/gdurelle/docrails' target='_blank'>répo git</a>
    du créateur de RailsDébutant.org. Il n'est donc pas forcément à jour par rapport au
    <a href='https://github.com/josrozen/docrails/tree/master/railties/guides/source' target='_blank'>répo officiel.</a>
    (N'hésitez pas à contribuer si vous êtes bon en anglais et que vous avez un peu de temps !)
  </li>
  <li>
    Les
    <a href='http://railscasts.com/' target='_blank'>RailsCast</a>
    Ces vidéos, certes en anglais, sont très concises et très bien présentées par le célèbre Ryan Bates !
  </li>
  <li>
    <a href='http://www.camilleroux.com/2011/09/08/comment-debuter-en-ruby-on-rails/' target='_blank'>Comment débuter en Ruby on Rails</a>
    de Camille Roux.
  </li>
</ul>
<h2 id='des-choses-a-ajouter-11'>Des choses à ajouter ?</h2>
<p>
  Si vous avez des références intéressantes à conseiller, n'hésitez pas à nous les faire parvenir dans les commentaires pour que nous mettions notre article à jour !
</p>
]]></content:encoded><description>Vous voulez vous lancer dans Ruby On Rails ? Nous ne pouvons que vous encourager ! Avec ce blog nous allons essayerde vous éclaircir sur différents points techniques ou théoriques. Cela étant dit, il y a quelques rudiments assez fondamentaux avant de se lancer dans Rails que nous allons vous présenter dans cet article.</description><feedburner:origLink>http://ontherailsagain.com/articles/avant-de-commencer-avec-ruby-on-rails</feedburner:origLink></item></channel></rss>

