2017-04-19 3 views
1

Je veux qu'une page de mon application web ruby ​​on rails soit inaccessible à l'un de mes modèles STI. J'ai deux modèles typeA et typeB héritant de l'utilisateur. J'ai utilisé le type de colonne dans la table User pour implémenter STI. J'utilise Devise gem pour les sessions utilisateur. Je veux une page Web 'http://localhost:3000/rate' inaccessible à mon utilisateur de typeA. Chaque fois qu'un utilisateur se connecte qui est de type 'typeA', il n'a pas la possibilité de voir le lien 'Rate'. Mais je ne veux pas non plus qu'il puisse accéder à cette page par le lien 'http://localhost:3000/rate'. S'il essaie d'y accéder via ce lien, je veux le signer et le faire se reconnecter. J'ai réussi cela en utilisant un morceau de code dans mon contrôleur avec la méthode spécifique pour 'rate'.Comment rendre certaines pages de mon application ruby ​​on rails inaccessibles à l'un de mes modèles d'utilisateur Devise User?

def rate 
    if current_user.type == "typeA" 
    sign_out(current_user) 
    redirect_to new_user_session_path 
    else 
    #Code for User of typeB 
    end 
end 

Cela fonctionne, mais je voulais savoir si cela peut se faire une meilleure façon en utilisant before_filter: authenticate_user! ou quelque chose d'autre En ce moment, ma part de before_filter ressemble à ce

before_filter :authenticate_user!, except: [:index, :show] 

Est-il possible que je peux faire un changement au code supérieur pour obtenir cette fonctionnalité.
P.S: Peut-être que cela peut être mieux fait si j'avais utilisé des rôles ou d'autres gemmes comme CanCan/Pundit mais il ne me reste plus beaucoup de temps pour soumettre mon projet, donc je ne veux pas entrer dans tout ça.

Répondre

1

Vous pouvez ajouter un autre before_filter sur le contrôleur dont vous souhaitez restreindre l'accès simplement pour confirmer votre type d'utilisateur STI sans surcharger le filtre authenticate_user! du module.

application_controller.rb

class ApplicationController < ActionController::Base 

    def confirm_user_type(user_type) 
    redirect_to new_user_session_path unless current_user.is_a?(user_type) 
    end 

end 

pages_controller.rb

class PagesController < ApplicationController 
    # must be authenticated to access 
    before_filter :authenticate_user! 
    # must be user of TypeA to access 
    before_filter { |c| c.confirm_user_type(TypeA) } 

    def rate 
    ... 
    end 
end 

Ensuite, vous pouvez utiliser le même filtre before_filter { |c| c.confirm_user_type(TypeB) } pour l'utilisateur STI type: 'TypeB'

+0

Je ne veux pas que l'ensemble du contrôleur soit inaccessible à typeA. Je veux seulement que la page "taux" lui soit inaccessible. Il y a d'autres méthodes comme index, create, show etc, qui devraient toujours lui être accessibles.Comment est-ce que je mets ça dans mon code? –

+0

vous pouvez utiliser l'option 'only:' pour le faire 'before_filter {| c | c.confirm_user_type (TypeA)},: only => [: rate] ' – sa77

+0

La page d'erreur que j'obtiens est /Users/Suvajit/Documents/Code/Rails/Mckenzie/app/controllers/dishes_controller.rb:4: syntaxe erreur, inattendu ':', attendez keyword_end .confirm_user_type (TypeA)}: only => [: rate]^ Le code que j'ai utilisé est 'before_filter {| c | c.confirm_user_type (TypeA)},: only => [: rate] ' –

0

Essayez ceci:

class ApplicationController 

    before_action :authenticate_user! 

    def authorize_user! 
    if current_user.type == "typeA" 
     sign_out(current_user) 
     redirect_to new_user_session_path 
    end 
    end 

end 

avec votre contrôleur:

class SomeController < ApplicationController 

    before_action :authorize_user!, except: [:index, :show] 

    def top_secret 
     ... 
    end 

end 

Je crois que si un before_action (le nouveau nom de before_filter) rend ou réoriente, l'action ne sera pas traitée.

+0

Ce ne fonctionne pas. Maintenant, chaque fois que j'essaie d'accéder même aux pages auxquelles A est autorisé à accéder, il le signe. De plus, lorsque je suis déconnecté et que j'essaie d'accéder à 'http: // localhost: 3000/rate', il affiche une page d'erreur Rails indiquant la variable inconnue 'current_user.type'. Avec le code que j'avais fait plus tôt, quand je suis déconnecté et que j'essaie d'accéder à 'http: // localhost: 3000/rate', il suffit de rafraîchir la page avec le message flash Devise indiquant 'Vous devez vous connecter ou inscrivez-vous avant de continuer "avec lequel je suis bon. En tout cas merci pour votre réponse. –

+0

Ah n'a pas réalisé authenticate_user! était Devise standard, donc vous ne devriez pas l'ignorer. Je pense que le code ici devrait fonctionner. Il va d'abord s'authentifier pour mettre current_user, puis autoriser. – mahemoff