IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Ruby on Rails Discussion :

Attribuer un ordre avec une table de jointure.


Sujet :

Ruby on Rails

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut Attribuer un ordre avec une table de jointure.
    Bonsoir,

    J'ai deux modèles (par exemple "clients" et "produits" pour reprendre les exemples que l'on trouve dans certains bouquins )
    Ils sont liés par une relation "has_and_belongs_to_many" (=> donc 3 tables)

    J'aimerais que lorsque l'on enregistre un "client" on puisse choisir des "produit(s)" parmis la liste des "produits" et que ceux-ci soient ordonnés (et que l'on puisse définir cette ordre).

    (oui, je sais c'est complétement tordu .... )

    Je voudrais déjà régler le problème d'architecture de la table de jointure. Je pensais à un champ "position" mais pour ajouter un "produit" à l'intérieur de la liste ca pose un problème.

    (si quelqu'un a déjà une idée pour la fabrication du formulaire, je suis preneur car je dois avouer que je ne me suis pas encore beaucoup penché sur la question)

    Merci

  2. #2
    Membre émérite
    Avatar de bolo
    Inscrit en
    Novembre 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 309
    Points : 2 695
    Points
    2 695
    Par défaut
    Je voudrais déjà régler le problème d'architecture de la table de jointure. Je pensais à un champ "position" mais pour ajouter un "produit" à l'intérieur de la liste ca pose un problème.
    C'est à dire ?

    On peut avoir le code des 3 models

    a+

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut
    Pour l'instant je défini l'architecture de l'application donc je n'ai pas encore le code des trois modèles.

    En gros, j'ai une relation N - N entre deux tables. (un "client" peut avoir acheté N "produits" et un "produit" peut avoir été acheté par N "clients").

    Donc en suivant les indications donnés par les bouquins sur Rails. Il faut que j'utilise "has_and_belongs_to" et crée une table de jointure.
    Mais comme je le décris plus haut, j'ai besoin d'ordonner les résulats d'une requête donnant la liste des "produits" associés à un "client" et que l'on puisse déterminer cette liste lors de l'enregistrement d'un "client". (cette liste peut évoluer => l'ordre de la liste et le nombres de "produits")

    Je pense que le problème peut être régler au niveau de la table de jointure.

  4. #4
    Membre émérite
    Avatar de bolo
    Inscrit en
    Novembre 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 309
    Points : 2 695
    Points
    2 695
    Par défaut
    En gros, j'ai une relation N - N entre deux tables. (un "client" peut avoir acheté N "produits" et un "produit" peut avoir été acheté par N "clients").
    plus haut tu dis que tu as 3 tables, elle est ou la troisième ?

    Donc en suivant les indications donnés par les bouquins sur Rails. Il faut que j'utilise "has_and_belongs_to" et crée une table de jointure.
    je n'utilise jamais has_and_belong_to, je me tourne vers has_many :through

    Mais comme je le décris plus haut, j'ai besoin d'ordonner les résulats d'une requête donnant la liste des "produits" associés à un "client"
    je suis peut fatiguée (fin de semaine etc ...) mais je comprends pas ce que tu veux faire.

    1. tu veux ordonner ta liste ok ? En fonction de quoi ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     et que l'on puisse déterminer cette liste lors de l'enregistrement d'un "client". (cette liste peut évoluer => l'ordre de la liste et le nombres de "produits")
    J'aurais utilisé 3 tables

    1. produit
    2. Client
    3. Liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    create_table "products" do |t|
     ######
    end
    create_table "clients" do |t|
      #######
    end
    create_table "listes" do |t|
      t.column "product_id",         :integer
      t.column "client_id",  :integer
    end
    les models
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Product < ActiveRecord::Base
      has_many :listes, :dependent => true
      has_many :clients, :through => :listes
    end
    class Clients < ActiveRecord::Base
      has_many :listes, :dependent => true
      has_many :products, :through => :listes
    end
    class Contribution < ActiveRecord::Base
      belongs_to :client
      belongs_to :product
    end
    Donc dans cette exemple, il y a un client et 2 produits
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    violon = Product.create
    voiture = Product.create
    bolo = Client.create
    bolo achete 2 produits
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Liste.create(:product => violon, :client => bolo)
    Liste.create(:product => voiture, :client => bolo)
    Retourne la liste de tous les achats de bolo
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bolo.products
    --> violon
    --> voiture
    Je sais pas si j'ai répondu a ta question

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut
    Merci pour cette réponse détaillée.

    Je ne connaissais pas "has_many :through" mais ca à l'air de donner la même chose.

    plus haut tu dis que tu as 3 tables, elle est ou la troisième ?
    la troisième table est "clients_produits" (avec les même champs que ta table liste (mais en respectant la convention de nomage "has_and_belong_to")

    Pour ce qui est d'ordonner la liste:

    En fonction de quoi ?
    De l'ordre défini à l'enregistrement du "client".
    => on choit x "produits" parmis la liste des "produits_enregistrés" et on les ordonne
    (cette liste peut être modifié en éditant le "client" par insertion / supression / changement de l'ordre)

    (je l'avais dit: c'est tordu ... )

  6. #6
    Membre émérite
    Avatar de bolo
    Inscrit en
    Novembre 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 309
    Points : 2 695
    Points
    2 695
    Par défaut
    réponse courte because je vais me coucher

    je crois que tu veux faire une liste sortable ? en gros un client a liste de produit.
    chaque produit a une postion dans la liste ?

    correct ?

    Si oui j'aurai rajouté le champs position et j'aurai utilisé la méthode sortable element.

    j'ai fait un post dessus
    http://blog.developpez.com/index.php...ec_un_dropaamp
    j'espère avoir répondu a ta question
    a+

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut
    Oui, c'est axactement ce que je veux faire.

    J'ai essayé "has_many :through", je l'ai essayé et çà à l'air de bien marcher.

    Pour la méthode "sortable", je n'ai pas compris comment modifier le fichier routes.

    "sortable" permet bien de ranger l'ordre de la liste ?
    exemple:
    j'ai 2 produits (p1,p2) ordonnés avec les "positions" (p1.position => 1 , p2.position =>2 )
    j'en ajoute un juste après p1. Est-ce que p2.position devient automatiquement "3" ?

    En tout cas merci beaucoup pour tes réponses.

  8. #8
    Membre émérite
    Avatar de bolo
    Inscrit en
    Novembre 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 309
    Points : 2 695
    Points
    2 695
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pour la méthode "sortable", je n'ai pas compris comment modifier le fichier routes.
    si non au lieu de mettre ceci
    :action => all_sort_items_path
    tu mets ça
    :action => sort
    "sortable" permet bien de ranger l'ordre de la liste ?
    exemple:
    Oui comme ca
    http://wiki.script.aculo.us/scriptac...tableListsDemo

    j'ai 2 produits (p1,p2) ordonnés avec les "positions" (p1.position => 1 , p2.position =>2 )
    j'en ajoute un juste après p1. Est-ce que p2.position devient automatiquement "3" ?
    sortable n'est qu'une fonction javascript. et la méthode sort ne récupère que la nouvelle position de l'item.

    Ce que tu veux faire si j'ai bien compris. En plus de trier ta liste , l'utilisateur puisse ajouter un item a une position précise

    moi j'aurais fait ca
    1. je créer mon nouvel item
    2. je chosis la position dans la liste
    3. je switch entre les deux items.

    voila

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut
    Merci beaucoup, je devrais pouvoir me débrouiller maintenant.

  10. #10
    Membre éclairé

    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 : 652
    Points
    652
    Par défaut
    Salut,

    En fait il y a plusieurs façon de faire ce que tu veux.
    "has_and_belongs_to_many" ou "has_many :through ou meme genere un model intermédiaire sont des solutions pour jointer.
    A toi de voir celle qu'il te faut, mais ce n'est pas ça qui va mettre dans l'ordre.

    Pour l'ordre, je n'ai pas non plus trés bien saisi par rapport à quoi tu voulais ordonner.
    ---> Jette un coup d'oeil à "act_as_list" qui me semble répondre à ce que tu cherches à faire.

  11. #11
    Membre émérite
    Avatar de bolo
    Inscrit en
    Novembre 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 309
    Points : 2 695
    Points
    2 695
    Par défaut
    ah oui j'avais pas pensé a act_as_list.

  12. #12
    Membre éclairé

    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 : 652
    Points
    652
    Par défaut
    Beh oui "Act_as_list" contient des methodes implicites qui permettent de mettre à jour l'ordre en automatique, pouvoir rajouter un enregistrement au mileu, et décaler tout le reste automatiquement...

    Mais tout dépend du besoin.
    Sinon on peut rajouter un truc tout simple dans le modele :
    Je ne saisi pas trés bien la problématique.
    Genre aussi on peut faire un champ ("updated_at") qui contient la date et l'heure de la dernire modif. Ensuite faire :
    ...
    Faudrait voir le MVC

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut
    J'ai utiliser act_as_list mais faute de doc (2 pages dans le bouquin d'Eyrolles et aucunes chez O'reilly) je ne sais pas l'utiliser dans le cas d'une relation "has_and_belongs_to many".

    J'aimerais en effet utiliser les méthodes d'act_as_list décrites dans le bouquin et pour commencer (en suivant l'exemple que je donnait précedement) donner le nom du produit précedent et du produit suivant sachant que l'action connait déjà le numéro du client et celui du produit.

    J'ai utilisé l'architecture décrite par bolo:
    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
    class produit < ActiveRecord::Base
      has_many :listes
      has_many :clients, :through => :listes
    end
     
    class Liste < ActiveRecord::Base
      belongs_to :client
      belongs_to :produit
      acts_as_list :scope => :client_id
    end
     
    class Client < ActiveRecord::Base
      has_many :listes
      has_many :produits , :through => :listes, :order => :position
    end
    Pour l'instant j'ai rempli manuellement le champ position de la table Listes

    J'ai appris sur le net l'existence de act_as_habtm_list mais le passage à une relation habtm entrainerait pas mal de changements et de debugage donc je préferais l'éviter (de plus je n'ai pas trouvé de tutos pour utiliser cette méthode)

    Pour l'instant mon modèle fonctionne bien sauf quand il s'agit d'utiliser "lower_item" (que je ne sais pas utiliser dans une relation has_many :through)

  14. #14
    Membre éprouvé

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 657
    Points : 910
    Points
    910
    Par défaut
    Salut,

    Après avoir un peu testé, effectivement il semble que ton problème ne soit pas évident

    Le problème c'est que les fonctions de acts_as_list sont seulement disponible dans Liste. Pour moi le seul moyen de trouver le produit suivant un autre dans la liste est de revenir à un objet Liste.
    Si tu connais le client et le produit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    produit_suivant = Liste.find(:first, :conditions => { :produit_id => params[:produit_id], :client_id => params[:client_id] }).lower_item.produit
    Oui c'est très moche

    Par contre rien ne t'empeche de définir des méthodes dans tes classes Client et Produit :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Client < ActiveRecord::Base
      has_many :listes
      has_many :produits , :through => :listes, :order => :position
     
      def produit_suivant(p)
        p = p.id if p.is_a?(Produit)
        liste = listes.find(:first, :conditions => {:produit_id => p}).lower_item
        liste.nil? ? nil : liste.produit
      end
    end
     
     
    Utilisation :
    >> bob = Client.find :first
    => #<Client:0x330034c @attributes={"id"=>"1", "login"=>"Bob"}>
    Avec un ID :
    >> bob.produit_suivant(3)
    => #<Produit:0x32e167c @attributes={"nom"=>"Produit1", "id"=>"1"}>
    >> bob.produit_suivant(1)
    => nil
    Avec un objet Produit :
    >> produit = Produit.find 3
    => #<Produit:0x32dc6cc @attributes={"nom"=>"Produit3", "id"=>"3"}>
    >> produit = bob.produit_suivant(produit)
    => #<Produit:0x32d4bc0 @attributes={"nom"=>"Produit1", "id"=>"1"}>
    >> produit = bob.produit_suivant(produit)
    => nil
    Peut-etre quelqu'un aura une meilleure solution ?
    Toute la documentation Ruby on Rails : gotapi.com/rubyrails
    Mes articles :
    > HAML : langage de template pour Ruby on Rails

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 110
    Points : 84
    Points
    84
    Par défaut
    Ca marche parfaitement, merci beaucoup.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/07/2012, 16h29
  2. Réponses: 3
    Dernier message: 29/10/2007, 13h04
  3. Réponses: 1
    Dernier message: 18/07/2007, 11h58
  4. Réponses: 6
    Dernier message: 19/03/2007, 20h04
  5. Réponses: 1
    Dernier message: 18/01/2006, 17h51

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