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 Discussion :

[RAILS 3] Déclencher une modification en base sur l'action sur une check_box


Sujet :

Ruby

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 57
    Par défaut [RAILS 3] Déclencher une modification en base sur l'action sur une check_box
    Bonjour à tous,

    Je débute sur rails et le développement web de manière générale, et me trouve confronté à un petit problème sans trop savoir quoi faire exactement.

    Voilà : j'ai en base une entité Recommendation avec un attribut :content (String) et un attribut :displayed(Boolean).
    J'affiche une liste de recommendations en utilisant le partial suivant :

    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
     
    <tr>
        <td class="recommendations">
            <span class="content">
                <%= wrap(recommendation.content)%>
            </span>
            <span class="timestamp">
                Posted <%=time_ago_in_words(recommendation.created_at)%> ago.
            </span>
        </td>
        <td>
            <%= form_for Recommendation.find(recommendation) do |f| %>
                <label>Display</label><%= f.check_box :displayed %>
            <% end %>
        </td>
    </tr>
    Maintenant ce que je voudrais c'est déclencher un update de l'entité en base dès que la check_box est cochée (:displayed => true) ou décochée (:displayed => false). Mais je ne vois pas comment faire.

    J'ai vu des personnes conseiller d'utiliser le helper observe_field mais je ne comprends pas comment l'utiliser avec la check_box de la façon dont elle est créée.

    D'avance, merci pour votre aide.

  2. #2
    Membre éclairé Avatar de Javix
    Inscrit en
    Juin 2007
    Messages
    531
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 531
    Par défaut
    D'abord, j'aurais déplacé la ligne Recomandation.find... dans le controller pour garder le modèle MVC sain, - la view n'a rien a voir avec les queries et les choses pareilles. Et dans ta form tu aurais qch de genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <%= form_for @rec do |f|%>
    ...
    <%end%>
    Je l'avais fait comme ça dans un des projets:
    dans la view:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <td>
    <%= check_box_tag 'rec[displayed]', "1", @rec.displayed, :onclick => toggle_value(@rec) %>
    <%= image_tag 'spinner.gif', :id => "spinner-#{@rec.id}",:style => 'display: none' %>
    </td>
    En suite définit la méthode 'toggle_value' dans un Helper (moi, je l'avais mis dans ApplicationHelper)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    def toggle_value(object)
        remote_function(:url => recomandation_url(:id => object),
          :method   => :put,
          :before => "$('#spinner-#{object.id}').show()",
          :after => "$('#spinner-#{object.id}').hide()",
          :with     => "this.name + '=' + this.checked")
      end
    Il ne reste qu'à mettre l'image 'spinner.gif' (voir le fichier ci-attaché) dans ton_app/public/images et c'est tout.
    Fichiers attachés Fichiers attachés

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 57
    Par défaut
    Merci pour cette réponse précise.

    Concernant :

    D'abord, j'aurais déplacé la ligne Recomandation.find... dans le controller pour garder le modèle MVC sain, - la view n'a rien a voir avec les queries et les choses pareilles. Et dans ta form tu aurais qch de genre:
    Code :
    <%= form_for @rec do |f|%>
    ...
    <%end%>
    J'utilise le renderer suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <%= render @recommendations %>
    pour afficher la liste de recommendations en utilisant le partial "_recommendation.html.erb". Et dans celui-ci la variable à utiliser est "recommendation". Du coup je suis obligé d'utiliser la méthode find(:id) pour retourner une instance à passer à mon form. Je devrais alors créer une méthode dans le application_helper qui me retourne le résultat de Recommendation.find(:id)...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 57
    Par défaut
    Ok, j'y suis presque maintenant avec cependant un dernier problème.

    J'ai gardé le check_box_tag comme ceci pour correspondre à mes besoins :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <td>
        <label>Display</label>
        <%= check_box_tag 'recommendation[displayed]', true, recommendation.displayed, {:onclick =>updated_displayed(recommendation)} %>
    </td>
    Dans le recommendations_helper j'ai définis la méthode suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    def updated_displayed(recommendation)
        remote_function(  :url => { :action => 'update_displayed', 
                                    :controller => 'recommendations', 
                                    :id => recommendation.id}, 
                          :with => "'displayed=' + this.checked")
    end
    Afin d'atteindre la méthode 'update_displayed' du controller il faut ensuite déclarer la route suivante dans le config/routes.rb :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    post 'recommendations/update_displayed/:id', :to => "recommendations#update_displayed"
    Et la méthode du controller :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    def update_displayed
        @recommendation.displayed = params[:displayed]
        unless @recommendation.save
          flash[:error] = "Error displaying the recommendation."
        end
        redirect_back_or current_user 
    end
    Voilà ça fonctionne, mais uniquement lorsque l'on coche la check_box.
    Si on la décoche l'update en base n'est pas effectué.

    Voici les logs :

    Tout d'abord si on coche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Processing by RecommendationsController#update_displayed as JS
    Parameters: {"authenticity_token"=>"2m7RqiFRVBoNAnOKSzx6m2z6Iof7ZCUkcp+xorhj+HU=", "displayed"=>"true", "id"=>"39"}
    Recommendation Load (0.2ms)  SELECT "recommendations".* FROM "recommendations" WHERE ("recommendations"."id" = 39) ORDER BY recommendations.created_at DESC LIMIT 1
    User Load (0.2ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
    CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
    AREL (0.4ms)  UPDATE "recommendations" SET "updated_at" = '2010-12-15 22:18:37.673495', "displayed" = 't' WHERE ("recommendations"."id" = 39)
    On voit bien l'appel à la méthode UPDATE.

    Maintenant si on décoche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Processing by RecommendationsController#update_displayed as JS
    Parameters: {"authenticity_token"=>"2m7RqiFRVBoNAnOKSzx6m2z6Iof7ZCUkcp+xorhj+HU=", "displayed"=>"false", "id"=>"39"}
    Recommendation Load (0.2ms)  SELECT "recommendations".* FROM "recommendations" WHERE ("recommendations"."id" = 39) ORDER BY recommendations.created_at DESC LIMIT 1
    User Load (0.2ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
    CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
    Plus de méthode UPDATE.

    Des idées pourquoi et comment corriger ce comportement ? Encore merci.

  5. #5
    Membre chevronné

    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
    Par défaut
    Salut,
    Des idées pourquoi et comment corriger ce comportement ?
    En fait c'est le comportement normal des check_box, lorsqu'on coche, c'est bon, ça passe, mais quand on décoche la dernière case, Rails ne le voit pas.
    Au départ, c'est pas prévu d'utiliser des check_box pour faire du js ou de l'ajax, directement dessus. Il faut utiliser un submit_to_remote, qui va envoyer ta série de coches, et encore je ne suis même pas sûr que ça fonctionne, lorsque toutes les cases sont vides.
    Perso, les checkbox j'ai laissé tomber, puisque ça correspond pas au besoin, par contre je sais que certains rajoutent une checkbox cochée, invisible, pour forcer Rails à agir...idée à suivre...si vraiment il faut utiliser check_box.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 57
    Par défaut
    Alors en suivant tous ces conseils j'ai laissé tombé l'utilisation des check_box et je suis passé à un link_to avec un image_tag d'une case cochée/décochée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <% if (recommendation.displayed?) %>
        <%= link_to image_tag("checked.png", :border=>0), :action => :hide, :id => recommendation %>
    <% else %>
        <%= link_to image_tag("unchecked.png", :border=>0), :action => :display, :id => recommendation %>
    <%end%>
    Dans le controller :

    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
     
      def display
        @recommendation.displayed = true
        unless @recommendation.save
          flash[:error] = "Error displaying the recommendation."
        end
        redirect_back_or current_user 
      end
     
      def hide
        @recommendation.displayed = false
        unless @recommendation.save
          flash[:error] = "Error hiding the recommendation."
        end
        redirect_back_or current_user 
      end
    Et j'obtiens un comportement similaire : l'appel à la méthode :display se fait sans problème et génère un UPDATE sur la base. Alors que l'appel à la méthode :hide affiche le flash[:error] et les logs ne présentent aucun appel à la méthode UPDATE.

    J'avoue ne pas comprendre...

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

Discussions similaires

  1. Impact d'une migration de base de donnée (erp) sur une plateforme BI
    Par Aurel5639 dans le forum Approche théorique du décisionnel
    Réponses: 5
    Dernier message: 03/07/2012, 21h10
  2. Réponses: 1
    Dernier message: 08/10/2010, 16h38
  3. Réponses: 2
    Dernier message: 30/03/2010, 02h26
  4. Réponses: 3
    Dernier message: 16/02/2007, 12h35
  5. Action sur le serveur via une page web
    Par raphxyz dans le forum Général Conception Web
    Réponses: 4
    Dernier message: 26/08/2006, 18h07

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