Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre expérimenté
    Avatar de kedare
    Homme Profil pro
    Network Operations Engineer
    Inscrit en
    juillet 2005
    Messages
    1 529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Network Operations Engineer

    Informations forums :
    Inscription : juillet 2005
    Messages : 1 529
    Points : 1 701
    Points
    1 701
    Par défaut Comment fonctionne le has_many ? (has_one vs belongs_to)
    Hello,
    j'essais d'utiliser le has_many, je doit dire que j'ai un peut de mal avec ce truc la (faut dire que tester rails sur oracle pour la premiere fois en meme temps etait pas la meilleur chose a faire :p).. J'ai donc crée 2 migrations et modeles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class CreateBooks < ActiveRecord::Migration
      def self.up
        create_table :books do |t|
          t.string :title
          t.string :description
          t.integer :pages
          t.integer :author_id
          t.integer :publisher_id
          t.string :image
     
          t.timestamps
        end
      end
     
      def self.down
        drop_table :books
      end
    end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class CreateAuthors < ActiveRecord::Migration
      def self.up
        create_table :authors do |t|
          t.string :first_name
          t.string :last_name
          t.string :phone
          t.string :address
     
          t.timestamps
        end
      end
     
      def self.down
        drop_table :authors
      end
    end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Book < ActiveRecord::Base
      has_one :author
    end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Author < ActiveRecord::Base
      has_many :books
    end
    Et fait quelques testes avec script/console, si j'ai bien comprit, en faite ca va juste mettre l'id de l'author dans le champ author_id de book ? j'avais cru comprendre que ça devais créer une table de join, bref j'ai pas encore tout comprit... et quand on a un has_many qui pointe sur un autre has_many, ca se passe comment ?
    merci

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    657
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 657
    Points : 895
    Points
    895
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Book < ActiveRecord::Base
      belongs_to :author
    end
    has_one remplace has_many dans une relation 1-1 (du côté du modèle qui n'a pas la référence donc).

    si j'ai bien comprit, en faite ca va juste mettre l'id de l'author dans le champ author_id de book ? j'avais cru comprendre que ça devais créer une table de join, bref j'ai pas encore tout comprit...
    Est-ce que tu comprends déjà bien les modèles Entité/Relation et comment les transcrire en SQL ? Une relation 1-N ou 1-1 n'a pas besoin de table de jointure, c'est seulement pour les relations N-N.
    De mon expérience, en visualisant le modèle E/R on voit tout de suite comment utiliser belongs_to/has_many/has_many :through/has_and_belongs_to_many et Rails permet juste de ne plus avoir à réfléchir au SQL à écrire.

    et quand on a un has_many qui pointe sur un autre has_many, ca se passe comment ?
    Tu parles peut-être de has_many :through (relation N-N) ? Tu peux trouver qques tutos là dessus (par exemple ici).
    Mais encore une fois je te conseille d'éviter de réfléchir en terme de "qui pointe sur quoi", mais de te ramener à un modèle E/R en identifiant les types de relations dont tu as besoin.
    Toute la documentation Ruby on Rails : gotapi.com/rubyrails
    Mes articles :
    > HAML : langage de template pour Ruby on Rails

  3. #3
    Membre expérimenté
    Avatar de kedare
    Homme Profil pro
    Network Operations Engineer
    Inscrit en
    juillet 2005
    Messages
    1 529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Network Operations Engineer

    Informations forums :
    Inscription : juillet 2005
    Messages : 1 529
    Points : 1 701
    Points
    1 701
    Par défaut
    Que signifie E/R ?
    Si non je n'ai jamais comprit la différence entre belongs_to et has_one :/
    Si non oui je sait comment c'est retranscrit, d'ailleur rails est assez étrange, il ne créer pas de foreign key...

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    657
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 657
    Points : 895
    Points
    895
    Par défaut
    E/R = Entité/Relation

    Dans une relation 1-1, tu as une table qui contient la foreign key (belongs_to) et la table référencée (has_one).
    Cela dit les relations 1-1 sont assez rare (et donc l'utilisation de has_one), car on peut souvent se contenter de regrouper les attributs des deux entités dans une seule table.

    Mais ce n'étais pas le sujet au départ : tu as une relation 1-N (one-to-many), tu dois donc utiliser belongs_to et has_many (Book belongs_to :author et Author has_many :books : comme souvent dans Rails ça se lit très bien )

    Et Rails ne crée pas les contraintes dans la base de données, mais il utilise évidement des foreign key. D'ailleurs, tout le monde n'est pas d'accord avec cette approche, et certains développeurs ajoutent également les contraintes dans la BDD pour mieux s'assurer de l'intégrité des relations.
    Toute la documentation Ruby on Rails : gotapi.com/rubyrails
    Mes articles :
    > HAML : langage de template pour Ruby on Rails

  5. #5
    Membre expérimenté
    Avatar de kedare
    Homme Profil pro
    Network Operations Engineer
    Inscrit en
    juillet 2005
    Messages
    1 529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Network Operations Engineer

    Informations forums :
    Inscription : juillet 2005
    Messages : 1 529
    Points : 1 701
    Points
    1 701
    Par défaut
    Mais je ne vois toujours pas vraiment la différence entre belongs_to et has_one, techniquement c'est la même chose ? puis si j'ai bien comprit, si l'on traduit ça en français :
    le Livre dépend de l'Auteur (belongs_to)
    le Livre possède un Auteur (has_one)
    les deux sont vrais, pourquoi donc utiliser belongs_to et pas has_one ?

    Voila un exemple de session :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Loading development environment (Rails 2.1.2)
    >> a = Author.find(10000)
    => #<Author id: 10000, first_name: "Chunk", last_name: "Noris", phone: nil, address: nil, created_at
    : "2008-11-08 21:44:49", updated_at: "2008-11-10 21:28:06", book_id: 10000>
    >> a.books
    => [#<Book id: 10000, title: "Chalala", description: nil, pages: nil, author_id: 10000, publisher_id
    : nil, image: nil, created_at: "2008-11-08 21:44:50", updated_at: "2008-11-08 21:45:32">]
    >> a.books[0]
    => #<Book id: 10000, title: "Chalala", description: nil, pages: nil, author_id: 10000, publisher_id:
     nil, image: nil, created_at: "2008-11-08 21:44:50", updated_at: "2008-11-08 21:45:32">
    >> a.books[0].author
    => #<Author id: 10000, first_name: "Chunk", last_name: "Noris", phone: nil, address: nil, created_at
    : "2008-11-08 21:44:49", updated_at: "2008-11-10 21:28:06", book_id: 10000>
    >>
    donc Book has_one :author fonctionne trés bien non ? pourquoi mettre belongs_to ?
    Si j'ai bien comprit c'est la même chose, sauf que belongs_to ajoute une FK ?
    merci

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    657
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 657
    Points : 895
    Points
    895
    Par défaut
    En utilisant le schéma de migration de ton premier post, avec has_one j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >> a.books[0].author
    ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: authors.book_id: SELECT * FROM "authors" WHERE ("authors".book_id = 1)  LIMIT 1
    Mais ça marche avec belongs_to :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >> a.books[0].author
    => #<Author id: 1, first_name: "Chuck", last_name: "Norris", phone: nil, address: nil, created_at: "2008-11-11 08:43:01", updated_at: "2008-11-11 08:43:01">


    Mais dans ton dernier post on voit que author a un champ book_id Je pense que tu as modifié ton schéma de données entre temps.
    Toute la documentation Ruby on Rails : gotapi.com/rubyrails
    Mes articles :
    > HAML : langage de template pour Ruby on Rails

  7. #7
    Membre expérimenté
    Avatar de kedare
    Homme Profil pro
    Network Operations Engineer
    Inscrit en
    juillet 2005
    Messages
    1 529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Network Operations Engineer

    Informations forums :
    Inscription : juillet 2005
    Messages : 1 529
    Points : 1 701
    Points
    1 701
    Par défaut
    Non non pourtant il y a toujours eu un book_id
    et j'ai aucune erreur...

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    657
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 657
    Points : 895
    Points
    895
    Par défaut
    Les migrations que tu as posté n'ont pas de champ book_id !

    Et essaye de rajouter un deuxième livre à ton auteur ... tu veras que ça ne marche pas avec ton has_one
    Toute la documentation Ruby on Rails : gotapi.com/rubyrails
    Mes articles :
    > HAML : langage de template pour Ruby on Rails

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    avril 2007
    Messages
    116
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : avril 2007
    Messages : 116
    Points : 100
    Points
    100
    Par défaut
    imaginons que tu ais une relation 1-1 bar/barman, un bar n'a qu'un barman et inversement un barman ne travaille que dans un seul bar :

    le model Bar possedera un barman_id, tu pourras donc dire que Bar belongs_to Barman et inversement que Barman has_one Bar (la table barman ne possède pas de bar_id).

  10. #10
    Membre confirmé

    Profil pro
    Inscrit en
    janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : janvier 2007
    Messages : 510
    Points : 644
    Points
    644
    Par défaut
    le Livre dépend de l'Auteur (belongs_to)
    le Livre possède un Auteur (has_one)
    les deux sont vrais, pourquoi donc utiliser belongs_to et pas has_one ?
    La fleche n'est pas dans le meme sens, sur le MCD

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : octobre 2006
    Messages : 124
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par kedare Voir le message
    Hello,
    [...] si j'ai bien comprit, en faite ca va juste mettre l'id de l'author dans le champ author_id de book ? j'avais cru comprendre que ça devais créer une table de join, bref j'ai pas encore tout comprit... et quand on a un has_many qui pointe sur un autre has_many, ca se passe comment ?
    merci
    Avec ton exemple, dans app/views/book/list.rhtml tu pourrais avoir du code comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <% for book in @books %>
      <tr>
        <td><%= book.title %></td>
        <td>
          <%= book.author.first_name %>
          <%= book.author.last_name %>
        </td>
      </tr>
    <% end %>
    qui renverra le titre, le nom et le prénom de l'auteur.

    Remarque la syntaxe nom_de_table.nom_de_champs ; avec la relation établie entre les tables, nom_de_table.nom_de_table.nom_de_champs. Ça permet de ne pas se préoccuper d'écrire soi-même des requêtes joignant plusieurs tables.

    Si la table author avait un champs d'adresse commune_id, et qu'il y avait une table des communes, tu pourrais avoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <%= book.author.commune.nom_de_commune %>
    qui renverrait le nom de la commune de l'auteur.

    J'espère que ça aide.

Discussions similaires

  1. [JSF] comment fonctionne <h:message> ?
    Par anitshka dans le forum JSF
    Réponses: 5
    Dernier message: 29/06/2005, 18h36
  2. Comment fonctionne TXmlDocumment ????
    Par almisuifre dans le forum C++Builder
    Réponses: 8
    Dernier message: 18/02/2005, 13h54
  3. comment fonctionne une interface graphique???
    Par elekis dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 28/10/2004, 00h10
  4. Comment fonctionne le ClassExplorer ?
    Par borisd dans le forum C++Builder
    Réponses: 7
    Dernier message: 30/09/2004, 18h44
  5. Comment fonctionne le CVS ?
    Par mathieu dans le forum CVS
    Réponses: 6
    Dernier message: 23/03/2004, 12h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo