Active record, shéma simple

Avé la communuauté…

Voila j’ai une ou deux petites questions en rapport avec Active Record
et la gestion des clés étrangère…

J’ai une base de donnée contenant 3 tables,

  • Client
  • Achat
  • Produit

Donc la logique simple, un client achète un produit…

Ma table Client répertorie les clients, la table produit l’ensemble de
ce que je vends, et la table Achat correspond à l’ensemble des achats
effectué…

Je pense mettre toutes les clés étrangere dans la table Achat (il me
semble que cela s’appel une table de jointure, mais je suis pas sur),
soit :
Achat

  • Client.id
  • Produit.id
    (ainsi que d’autre champs comme la date de l’achat etc…)

Est-ce ce schéma vous parait cohérent et donc logique ?
il me permettra de pouvoir récupérer par exemple la liste des client
ayant acheté un produit X ?

et une derniére question, quelle est la logique d’utilisation de
belongs et has dans ce cas pour ces 3 models ?

Merci beaucoup…

On 6/2/07, Differenthink [email protected] wrote:

  • Client.id
  • Produit.id
    (ainsi que d’autre champs comme la date de l’achat etc…)

Est-ce ce schéma vous parait cohérent et donc logique ?

C’est tout à fait ça. On appelle ça une relation N-N entre Produit et
Client, car un N produits on N clients et inversement.

il me permettra de pouvoir récupérer par exemple la liste des client
ayant acheté un produit X ?

Oui, tu pourras récupérer pour un client la liste des produits qu’il a
acheté et la liste des clients qui ont acheté un Produits.

et une derniére question, quelle est la logique d’utilisation de
belongs et has dans ce cas pour ces 3 models ?

tout d’abord selon la convention Ruby On Rails, on indique les
colonnes de clé étrangères par nomdelatable_id donc ta table de
liaison sera :

client_id
produit_id

Mais là où Rails est totalement génial, c’est que toi tu n’auras
quasiement rien à gérer. Il faudra dans ta migration créer une table
qui aura comme nom la jointure des nom au pluriel de tes deux tables
comme suit ci-dessus :

create_table :clients_produits do |t|
t.column :client_id, :int
t.column :produit_id, :int
end

Ensuite, il ne te reste plus qu’a mettre has_and_belongs_to_many
:produits dans client et pareil avec clients dans produit. Ainsi tu
auras accès en direct à des listes d’objet Client dans produit et
Produit dans Client.

Les magies de rails sont facilement découvrable dans la documentation.
Dans ton cas, la doc compléte de ActiveRecords[1].

Plus de détails avec les associations[2] et has_and_belongs_to_many[3]

Bon week-end

[1] : ActiveRecord::Base
[2] :
ActiveRecord::Associations::ClassMethods
[3] :
ActiveRecord::Associations::ClassMethods


Cyril M.

Merci beaucoup pour cette réponse ultra complete…
Il y a juste une chose de plus que je me demande, cette table de
jointure, qui possede les deux foreign key, je peux aussi lui ajouter
d’autre champs ? (comme la date d’achat etc…)

il est vraie que rails facilitie bcp la vie, même un peu trop quand on
début car on a du mal a voir ce que l’on fait et ce que rails fait
pour nous…

On 6/2/07, Differenthink [email protected] wrote:

Merci beaucoup pour cette réponse ultra complete…
Il y a juste une chose de plus que je me demande, cette table de
jointure, qui possede les deux foreign key, je peux aussi lui ajouter
d’autre champs ? (comme la date d’achat etc…)

Tu peux tout à fait utiliser d’autre champs. Mais dans ces conditions,
tu ne pourras pas utiliser la création de la table implicite. Il faut
que tu fasses un objet ActiveRecord avec les deux clés étrangères et
des has_many et through. Si tu veux un bonne exemple de ce dernier
point sur le through Jean-françois m’avais fait un bon exemple avec
une table qui liait 3 tables au lieu des 2 de ton cas[1].

il est vraie que rails facilitie bcp la vie, même un peu trop quand on
début car on a du mal a voir ce que l’on fait et ce que rails fait
pour nous…

C’est pour quoi il faut lire sans arrêt la documentation. Je te
conseillerais aussi de lire du code Rails, comme par exemple le code
de Mephisto qui est très bien
rédigé.
[1] :
http://groups.google.com/group/railsfrance/tree/browse_frm/thread/d5063814c1d1222e/7165af6735dd198b?rnum=1&q=3+table&_done=%2Fgroup%2Frailsfrance%2Fbrowse_frm%2Fthread%2Fd5063814c1d1222e%2F8d8a9b23c02021ea%3Flnk%3Dgst%26q%3D3%2Btable%26rnum%3D1%26#doc_3df4614725211afc


Cyril M.

Bon je viens de lire l’explication de Jean-Francois, c’est plutot
claire… je pense avoir compris…

Si je résume en fait, rails est capable de faire des tables de
jointure implicite (sans creer la table en sql) mais que pour deux
foreign key et rien de plus…
en revanche si l’on crée la table de jointure nous même (en sql), on
fait ce que l’on veut… et on utilise :through (qui doit être a mon
avis utilisé implicitement qd c est rails qui prend un charge la table
de jointure sans table sql)…

Vu le shéma de la BDD que je compte mettre en place, je sens qu’il va
me falloir une semaine rien que pour ca… :confused:
d’ailleurs voici un exemple plus complet, ca serait sympa si tu
pouvais me dire si mon shéma est correcte :

Tables :
Client
Produit
Achat
Categorie
Admin

Le client fait un Achat de Produit. Le Produit est disposé dans une
Categorie. Le Produit est geré par un Admin

Je pense donc a qqch comme cela pour les clés étrangeres:

ACHAT
client.id
produit.id

PRODUIT
admin.id
categorie.id

Donc pour la table ACHAT je fait ce que l’on disait plus haut, une
table de jointure “manuelle”…
et si j’ai bien compris pour la table PRODUIT cela va être la même
chose…

La class PRODUIT devrait donc ressembler à cela :
has_many achat
has_many client through => :achat

belongs_to :admin
belong_to :categorie

ca semble correcte ?

Encore une fois merci pour tout…

Exact, qques lignes dessus ici http://www.forum-rails.com/forums/5/
topics/6
Seb

Cyril :

Les créations des tables ne se font à l’heure actuel que par
script SQL ou l’utilisation des scripts de migration (J’ai cru
lire sur un blog du planet Rails que dans le futur des tâches
rake de create et de drop de la BDD existeront)

Pas envie de répondre au thread (ptêtre demain oops… aujourd’hui)
maintenant, mais sur ce point, ça commence à être implémenté
dans Edge.

http://dev.rubyonrails.org/changeset/6849

– Jean-François.


À la renverse.

Effectivement ca bouge vite dans le monde Rails, je vais m’en tenir à
essayer d’accrocher les wagons avant la locomotive…
en tout cas super sympa ce google group rails france…

Bonne fin de WeekEnd

On 6/2/07, Differenthink [email protected] wrote:

Bon je viens de lire l’explication de Jean-Francois, c’est plutot
claire… je pense avoir compris…

Si je résume en fait, rails est capable de faire des tables de
jointure implicite (sans creer la table en sql) mais que pour deux
foreign key et rien de plus…

Rails n’est pas capable de géré la création de tables. En effet,
ActiveRecord sait lire le contenu d’une base de donnée et ainsi créer
les méthodes adéquates en fonction de la configuration que tu as
donnée à tes classes hérités d’ActiveRecord. Les créations des tables
ne se font à l’heure actuel que par script SQL ou l’utilisation des
scripts de migration (J’ai cru lire sur un blog du planet Rails que
dans le futur des tâches rake de create et de drop de la BDD
existeront)

en revanche si l’on crée la table de jointure nous même (en sql), on
fait ce que l’on veut… et on utilise :through (qui doit être a mon
avis utilisé implicitement qd c est rails qui prend un charge la table
de jointure sans table sql)…

Non ce n’est pas ça. Dans le cas des liaison 1-1 ou 1-N de tes objets,
il faut utiliser les méthodes has_many, belongs_to et has_one et un
champs dans la table correspondant à la clé étrangères dans la table
qu’il faut.

Ensuite l’option though, permet juste de dire quel table fait la
jointure pour la donner de façon explicite si tu n’es pas dans le cas
de la convention. Rails, c’est convention plutôt que configuration. Au
vu de ton exemple suivant tu as compris la logique final. Peut-être
pas les truc qui sont implicite et surtout dans quel cas. J’avoue que
c’est souvent ce qui m’embete avec rails et qui en fait sa magie.

Vu le shéma de la BDD que je compte mettre en place, je sens qu’il va
me falloir une semaine rien que pour ca… :confused:

Imagine avec Hibernate et le mapping en XML :slight_smile:

Le client fait un Achat de Produit. Le Produit est disposé dans une
categorie.id
belongs_to :admin
belong_to :categorie

ca semble correcte ?

Oui ca semble correcte à première vu. Après les test unitaires te
diront si finalement le comportement est bien celui que tu veux. En
Agile programming, on test avant d’implémenter. Ca permet au moins
d’être sur que son test échoue :stuck_out_tongue:

Encore une fois merci pour tout…

Beaucoup de communauté opensource servent à ça. Actuellement, j’ai le
temps de répondre. Les prochaines fois ca pourra être toi qui répondra
à des nouveaux :slight_smile:


Cyril M.