2010-10-22 4 views
4

D'abord, un exemple de ce que je suis en train de faire:Rails: Affichage d'une vue différente pour la même URL?

  1. Si vous allez à http://www.meetup.com et vous n'êtes pas connecté, vous voyez une page qui affiche « Faites quelque chose • Apprendre quelque chose ... », etc. Mais quand vous êtes connecté, cette même page (URL) affiche 'Bienvenue, xxx ... Ce qui se passe ...', etc. qui vous est propre.
    C'est ce que j'essaie de faire dans mon application aussi.

Comment faire à ce sujet dans Rails 2.3.8?

, j'ai Jusqu'à présent:

  1. Un AboutsController destiné à servir des pages semi-statiques (souhaite le propos n'a pas été au pluriel!)
  2. route Root est map.root => :controller => "about".

Maintenant, quand un non-connecté-utilisateur va au http://www.abc.com, il obtiendrait le contenu de la vue about/index. Jusqu'ici tout va bien.

Mais, lorsqu'un utilisateur est connecté , je veux que la vue products/index doit être affiché pour la même URL à savoir http://www.example.com URL (et non http://www.example.com/products)

Est-ce possible dans Rails 2.3.8?

+3

Ajoutez 'inflect.uncountable 'about'' à inflector.rb et vous pouvez avoir votre AboutController. –

+0

Merci pour le pourboire! – Zabba

+0

Les noms de contrôleurs n'ont pas besoin d'être pluriels à moins que vous ne diffusiez des éléments de base de données et que vous souhaitiez utiliser des itinéraires de ressources, n'est-ce pas? – Matchu

Répondre

3

La façon la plus simple de le faire est d'utiliser un élément appelé before_filter. C'est une commande en haut de votre contrôleur qui est appelée avant toute action dans ce contrôleur (que vous voulez). Normalement, vous voudrez faire la même vérification pour plus d'une action dans le contrôleur, il n'est donc pas logique de mettre cette vérification directement dans chaque action. Supposons que vous ayez un contrôleur de commentaires et que vous souhaitiez que les actions d'édition, de mise à jour et de destruction soient réservées à un utilisateur connecté. C'est très commun. Regardons un exemple. Par souci de concision, je ne vais pas préciser toutes les actions du contrôleur, tout le truc unique:

class CommentsController < ApplicationController 
    before_filter :user_logged_in?, :only => [:edit, :update, :destroy] 

    # all your actions would go here - index, show, etC# 

    protected 

    def user_logged_in? 
    redirect_to dashboard_path unless current_user 
    end 
end 

Dans l'exemple ci-dessus, la méthode user_logged_in? va exécuter avant la modifier, mettre à jour ou de détruire les actions sont courir. Si un rendu ou une redirection est appelé à l'intérieur de cette méthode, les rails s'arrêteront rapidement et ne lanceront jamais l'action. C'est pourquoi cela s'appelle un filtre. Au lieu de cela honorera la demande de rendu ou de redirection donnée.

La méthode current_user est une aide commune que la plupart des plugins d'authentification utilisateur vous donnent, ce qui est généralement nul s'il n'y a pas d'utilisateur courant. Donc, notre méthode de filtrage indique aux rails de rediriger vers un certain chemin, sauf si l'utilisateur est connecté.

C'est la façon de faire les rails de facto de ce genre. Très bonne question

2

C'est certainement possible. Vous pouvez rendre selon des vues dont vous avez besoin conditionnellement comme ceci:

def index 
    if current_user 
    render :action => 'products', :controller => 'index' 
    else 
    render :action => 'index', :controller => 'about' 
    end 
end 

En supposant que vous authentifier avec Authlogic, DEVISE. Quelle que soit la logique que vous utilisez pour déterminer si un utilisateur est connecté entrerait dans le conditionnel.

+0

Vous avez eu le concept, merci! Mais il peut s'agir d'une faute de frappe dans votre code (: controller devrait être 'about' pour les deux?) – Zabba

+0

Oui, quelle que soit la vue à rendre, c'est la syntaxe de base pour le rendre conditionnellement. – njorden

+1

Ce n'est pas ma méthode préférée, mais la façon dont cela est fait dans l'exemple est incorrecte. Un appel à "render" n'affichera que la vue que vous avez demandée. Il n'exécute pas réellement l'action d'index AboutController #. Si l'action ne fait rien, cela fonctionnera bien. Mais si l'action d'index AboutController # définit des variables, celles-ci ne seront pas définies et la vue échouera. La redirection devrait être utilisée à la place. –

1

J'ai vu beaucoup de sites Web gérer cela avec une redirection vers, par exemple, /dashboard, pour garder leur application aussi propre que possible en interne. Pas besoin de s'énerver à ce sujet étant toujours l'URL racine, bien que ce soit clairement possible, comme l'indiquent les autres solutions :)

+0

C'est vrai aussi. Maintenant, je suis confus quant à l'approche à adopter :) – Zabba

+0

@Zabba: Je pense que les réponses sur la réponse @ njorden couvrent: vous voulez probablement montrer des choses à l'utilisateur sur leur tableau de bord, qui comprend probablement certaines choses que vous voulez définir en tant que variables d'instance, la redirection est probablement plus propre dans l'ensemble. Mais tout dépend des exigences de votre application. – Matchu

Questions connexes