2010-09-26 15 views
1

J'ai un contrôleur d'administration pour une page d'une application Rails 3 qui répertorie tous les comptes de modèle d'utilisateur dans une table et une partie de chaque ligne doit être un lien (avec confirmation) pour basculer l'attribut is_admin de mon modèle d'utilisateur. Je voudrais le faire en permettant à un administrateur de cliquer sur le texte dans la cellule du tableau qui répertorie l'état actuel de l'admin (c.-à-d. En cliquant sur "Non" définira is_admin à true). Pour l'instant, je ne suis pas intéressé par une approche AJAX sophistiquée, et ne tenons pas compte du fait que d'un point de vue UI, cliquer sur un texte indiquant l'état d'un objet pour basculer cet état n'est pas forcément le meilleur choix. Ce que je me demande, est-ce que cela peut être fait dans un seul appel link_to, ou ai-je besoin de construire un formulaire autour d'elle? Mon contrôleur admin est défini comme 'resources: admin' dans routes.rb et rake routes répertorie une action PUT avec le chemin nommé 'admin' qui appelle la méthode de mise à jour admin #.Basculer une valeur unique dans un modèle, le tout à partir d'un lien vers

Voici ce que j'ai jusqu'à présent:

<%= link_to (user.is_admin ? "Yes" : "No"), 
      admin_path(:user => {:id => user.id, :is_admin => !user.is_admin}), 
      {:confirm => "Are you sure?", :method => :put} %> 

Ma pensée est que je passe dans suffisamment de données dans un appel RESTful à la méthode de mise à jour afin que je puisse modifier tout cet attribut. Je me rends compte qu'il serait possible de simplement définir une méthode appelée toggle_admin, transmettre seulement l'ID et opérer sur ce membre du modèle, mais je pensais que cette approche serait aussi RESTful que possible, et je suis plus intéressé à apprendre l'étendue à qui je peux utiliser link_to ici.

Mon erreur que je reçois est:

No route matches {:action=>"destroy", :controller=>"admin", :user=>{:id=>1, :is_admin=>false}} 

Je ne sais pas pourquoi il essaie d'invoquer la méthode détruire, il semble être la dernière chose dans ma liste des itinéraires spécifiques admin:

rake routes | grep admin 
      site_admin  /admin(.:format)    {:controller=>"admin", :action=>"index"} 
      admin_index GET /admin(.:format)    {:action=>"index", :controller=>"admin"} 
      admin_index POST /admin(.:format)    {:action=>"create", :controller=>"admin"} 
      new_admin GET /admin/new(.:format)   {:action=>"new", :controller=>"admin"} 
      edit_admin GET /admin/:id/edit(.:format)  {:action=>"edit", :controller=>"admin"} 
       admin GET /admin/:id(.:format)   {:action=>"show", :controller=>"admin"} 
       admin PUT /admin/:id(.:format)   {:action=>"update", :controller=>"admin"} 
       admin DELETE /admin/:id(.:format)   {:action=>"destroy", :controller=>"admin"} 

Je pensais que je passe la mauvaise méthode et il est en défaut à la dernière, mais this page suggère que vous pouvez définir :method => avec votre :confirm par exemple comme une option HTML. Donc, fondamentalement, ma question est de savoir si je suis capable de faire un appel RESTful non GET via link_to comme ça? J'ai supposé que Rails construirait juste un petit mini-formulaire dans les coulisses pour moi.

Plus de code source dans this gist.

Répondre

1

Utilisez ceci:

div_for @user do 
    link_to (@user.is_admin? ? "Yes" : "No"), [@user, :toggle], :confirm => ... 
end 

et cet itinéraire:

map.resources :users, :as => "admin", :member => { :toggle => :put } 

et cette méthode de commande:

class UsersController < ... 
    def toggle 
    @user = User.find params[:id], :lock => true 
    @user.is_admin = [email protected]_admin? 
    @user.save! 
    if request.xhr? 
     render :update {|page| page[@user].replace_html @user } 
    else 
     redirect_to @user 
    end 
    end 
end 

Essayer de gérer cela avec un lien vers l'action de mise à jour devient juste trop compliqué pour un seul cas (comme vous l'avez déjà compris, il y a des pièges). Utiliser link_to_remote pour ce cas est un meilleur candidat (juste au cas où j'ai déjà ajouté la gestion ajax pour montrer que ce n'est pas trop chic).

+0

Merci @ hurikhan77. Je vais donner celui-ci un coup le lendemain ou deux. –