2009-08-24 7 views
6

dans mon application, j'ai un modèle "Utilisateur". Chaque utilisateur peut avoir plusieurs (adresses e-mail) qui sont définis dans le modèle « Adresse »:Un contrôleur, différentes vues pour les utilisateurs normaux et les administrateurs

Class User < ActiveRecord::Base 
    has_many :addresses 


    def is_authorized(op) 
    # returns true or false 
    end 

    def is_owned_by(user) 
    # returns true or false 
    end 
end 

Class Address < ActiveRecord::Base 
    belongs_to :user 
end 

intérieur de la classe AddressController, l'utilisateur actuellement connecté est disponible dans la variable d'instance « @user ». Le contrôleur empêche les utilisateurs ordinaires d'éditer, de supprimer, d'afficher etc. les adresses qui ne leur appartiennent pas - mais il permet à un utilisateur administratif de les modifier. La classe AddressController peut demander à AddressModel si l'utilisateur actuellement connecté effectue des opérations normales ou super-utilisateur.

Tout cela fonctionne bien et les mises à jour de base de données sont faites comme prévu, cependant, j'aimerais vraiment avoir des vues HTML différentes selon le mode de fonctionnement. Je ne peux penser à deux façons d'y parvenir:

  1. Faire le mode de fonctionnement (normal/privilégié) connus dans la classe AddressController (en utilisant une variable d'instance, par exemple @privileged) et d'utiliser un « si » déclaration la vue.
  2. Utilisez quelque chose comme un "after_filter" dans le contrôleur d'adresse pour rendre une mise en page différente.

S'il est possible d'afficher les résultats de l'exécution d'un seul contrôleur dans deux dispositions complètement différentes, en fonction de son mode de fonctionnement, quel est le meilleur moyen d'y parvenir?

Merci à l'avance Stefan

Répondre

9

Vous pouvez spécifier la vue à utiliser pour afficher le résultat d'une action dans l'action elle-même. Vous pouvez également spécifier la mise en page à utiliser aussi. Ainsi, par exemple:

def my_action 
    if @user.is_authorised(...) 
    render :action => 'admin_action', :layout => 'admin' 
    else 
    render :action => 'non_admin_action', :layout => 'non_admin' 
    end 
end 

Cela rendra soit admin_action.html.erb ou non_admin_action.html.erb en fonction de la valeur retournée par is_authorised. L'option :layout est, er, facultative et fait référence à une disposition dans les vues/mises en page. Il existe diverses autres options de l'appel de rendu que vous pouvez trouver dans le documentation for render.

+0

Merci. Mais il semble que si je fais cela, je quitterais le chemin de "convention sur configuration". Je suis un peu inquiet - c'est ma première application Rails - devrais-je déjà diverger de ce que tout le monde semble faire? – cite

+0

Eh bien, sans doute la convention est de rendre une vue pour une action, mais je peux voir ce que vous obtenez. Si vous recherchez simplement différentes configurations, la solution de Staelen est une bonne solution. Si vous voulez vraiment afficher des vues différentes en fonction de la logique de l'action, je ne suis pas sûr que cela soit assez proche de la convention de base pour ne pas spécifier quelle vue vous voulez rendre. – Shadwell

+0

Je pense que je vais essayer la solution de Staelen pour la mise en page et celle pour le gabarit à rendre. Merci encore. – cite

3

Vous pouvez simplement appeler la méthode render manuellement à la fin de votre action de contrôleur:

if @privileged 
    render :action => 'show_privileged' 
else 
    render :action => 'show' 
end 

Cela rendra app/views/myview/show_privileged.html.erb ou app/views/myview/show.html.erb. Vous pouvez également utiliser l'option :template pour donner un fichier de modèle explicite à la méthode de rendu.

+0

Merci, Dave. – cite

6

Vous pouvez spécifier la mise en page de la vue de ce contrôleur particulier, ou l'ensemble de l'application dans le contrôleur d'application par:

class SomeController < ApplicationController 
    layout :set_layout 

    def set_layout 
    @user.is_authorized(...) ? "privileged_layout" : "normal_layout" 
    end 

    ... 
end 

Vous pouvez essayer de comprendre ici: http://guides.rubyonrails.org/layouts_and_rendering.html#using-render, sous 2.2.12 trouver Layouts

Hope this helps =)

+0

Oh, c'est une bonne idée. Merci beaucoup! – cite

2

Si c'est le seul contrôleur dans votre application où vous êtes si/else'ing dans le lieu qui est probablement très bien. Si vous commencez à faire ce type de logique partout, cela devrait vous dire que vous en faites trop à la fois.La réponse que vous avez acceptée (ce qui est bien et fonctionne!) A une disposition différente et une vue différente, à moi qui dit que le contrôleur en fait trop - je diviserais ceci en contrôleur d'admin.

+0

Ceci. Tu avais raison. J'ai essayé de faire trop de choses à la fois - l'idée de disposer de toutes ces actions dans deux modes de fonctionnement était trop intrigante. J'ai écrit un contrôleur d'administration dédié. Merci. – cite

0

Vous devez placer des actions d'administration dans un espace de noms administratif et le limiter ici. Créez un répertoire appelé admin dans votre controllers et ajouter un _application_controller.rb_ là:

class Admin::ApplicationController < ApplicationController 
    before_filter :check_authorized 

    private 
    def check_authorized? 
     if !logged_in? || !current_user.admin? 
     flash[:notice] = "You've been very bad. Go away. 
     redirect_to root_path 
     end 
    end 
end 

Maintenant, vous pouvez mettre des contrôleurs dans cet espace de noms et de les faire hériter de Admin::ApplicationController aussi.

Questions connexes