Héritage sous Rails

édité Le 16/05/2010 à 10:03 par Trinoo

héritage Ruby on Rails

Sans m'attader dans une explication, un exemple sera plus simple :
Je vais prendre le cas de "trinoo.net" qui comprend des Articles, des Nouvelles (infos) et des Topics sous le forum.
La structure de ces trois est quasiment identique. Ce qui différe, c'est leur nature. Il suffit donc de créer une seule et unique table "posts" qui contiendra les enregistrements (confondus) de ces trois derniers.

Afin de différencier les "articles" des "infos" et des "topics" on rajoutera un champs dans la table, nommé type, ce dernier aura trois valeurs (dans notre cas) : soit info ou bien article ou bien topic. Cet attribut sera la clé pour que les modèles : info, article et topics arrivent à retrouver leurs enregistrements confondus dans le modèle post parent.

Voilà à quoi ressemble la structure de la table "posts"

class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.string :type
      t.string :titre
      t.string :url
      t.string :bartitle
      t.string :altlink
      t.text :short_body
      t.text :body
      t.user_id :integer #clé étrangère pour identifier l'auteur
      t.forum_id :integer #clé étrangère qui concerne uniquement le modèle Topic

      t.timestamps
    end
  end

  def self.down
    drop_table :posts
  end
end
et voici de même les modèles
class Post < ActiveRecord::Base

  has_many :comments
  belongs_to :user
  
  validates_presence_of :titre, :url, :bartitle, :body
  validates_uniqueness_of :url
  
end
class Article < Post #le modèle Article hérite du modèle Post
    
  validates_presence_of :shortbody
  
end
class Info < Post #le modèle Info hérite du modèle Post
   
end
class Topic < Post #le modèle Info hérite du modèle Post
  
  belongs_to :forum
  validates_presence_of :titre
  before_validation :fixattributes

  protected
  
  def fixattributes 
  .....
  end

end

Comme vous voyez, un Article exige la présence d'une "introduction" : (shortbody), ce qui n'est pas le cas pour les "infos"

L'utilisation ou non des champs existants dans la table sera déterminée par le controleur ainsi que les tests de validations dans le modèle en question.

On aurait pu créer à la base le modèle parent Article dont Info et topic seront héritiers. Mais, je préfére garder Post pour une souplesse dans de futurs changements, si jamais j'aurais besoin de créer une nouvelle catégorie de "posts"

Cette structure peut nous simplifier la mise en place d'un formulaire de recherche de contenu sur le site en allant explorer un seule table (posts) au lieu de plusieurs. Merci l'héritage.