简体   繁体   中英

Redirect admin user to Different Page - Ruby on Rails

Im currently following Michael Hartl's tutorial. I'm making a few modifications to suit my App. One piece of functionality that I need to include is that when a user logs in as admin they are directed to a different page where they in turn can create or delete more users etc. I have created a boolean in the users table called admin and set the admin record to TRUE.

Here is my users_controller.rb

    class UsersController < ApplicationController

    before_action :logged_in_user, only: [:index, :edit, :update]
    before_action :correct_user,   only: [:edit, :update]


      def index
        @users = User.all
      end

      def show
        @user = User.find(params[:id])
      end

      def new
        @user = User.new
      end


      def create
        @user = User.new(user_params)
        if @user.save
          log_in @user
          flash[:success] = "Welcome to the Sample App!"
          redirect_to @user
        else
          render 'new'
        end
      end

      def edit
        @user = User.find(params[:id])
      end

      def update
        @user = User.find(params[:id])
        if @user.update_attributes(user_params)
          flash[:success] = "Profile updated"
          redirect_to @user
          # Handle a successful update.
        else
          render 'edit'
        end
      end

      private

        def user_params
          params.require(:user).permit(:name, :email, :password,
                                       :password_confirmation)
        end

         # Before filters

        # Confirms a logged-in user.
        def logged_in_user
          unless logged_in?
            store_location
            flash[:danger] = "Please log in."
            redirect_to login_url
          end
        end


        # Confirms the correct user.
        def correct_user
          @user = User.find(params[:id])
          redirect_to(root_url) unless current_user?(@user)
        end


    end

Below is my sessions_controller

    class SessionsController < ApplicationController
       def new
      end

      def create
            user = User.find_by(email: params[:session][:email].downcase)
        if user && user.authenticate(params[:session][:password])
           log_in user
           params[:session][:remember_me] == '1' ? remember(user) : forget(user)
           #remember user
           #redirect_to user
           redirect_back_or user
          # Log the user in and redirect to the user's show page.
        else
          # Create an error message
          flash.now[:danger] = 'Invalid email/password combination'
          render 'new'
        end
      end

       def destroy
        log_out if logged_in?
        redirect_to root_url
      end

    end

My sessions_helper next

    module SessionsHelper

        # Logs in the given user.
      def log_in(user)
        session[:user_id] = user.id
      end

        # Remembers a user in a persistent session.
      def remember(user)
        user.remember
        cookies.permanent.signed[:user_id] = user.id
        cookies.permanent[:remember_token] = user.remember_token
      end

       # Returns the user corresponding to the remember token cookie.
      def current_user
        if (user_id = session[:user_id])
          @current_user ||= User.find_by(id: user_id)
        elsif (user_id = cookies.signed[:user_id])
          user = User.find_by(id: user_id)
          if user && user.authenticated?(cookies[:remember_token])
            log_in user
            @current_user = user
          end
        end
      end          def logged_in?
        !current_user.nil?
      end

       # Logs out the current user.
      def log_out
        forget(current_user)
        session.delete(:user_id)
        @current_user = nil
      end

        # Forgets a persistent session.
      def forget(user)
        user.forget
        cookies.delete(:user_id)
        cookies.delete(:remember_token)
      end

       # Returns true if the given user is the current user.
      def current_user?(user)
        user == current_user
      end

        # Redirects to stored location (or to the default).
      def redirect_back_or(default)
        redirect_to(session[:forwarding_url] || default)
        session.delete(:forwarding_url)
      end

       def redirect_to_admin_page
        redirect_to 'index'
      end

      # Stores the URL trying to be accessed.
      def store_location
        session[:forwarding_url] = request.url if request.get?
      end 

and finally my routes file

    Rails.application.routes.draw do

      get 'sessions/new'

      root                'static_pages#home'
      get    'static_pages/home'
      get    'static_pages/landing'
      get    'home' => 'static_pages#home'
      get    'landing' => 'static_pages#landing'
      get    'signup'  => 'users#new'
      get    'login'   => 'sessions#new'
      post   'login'   => 'sessions#create'
      delete 'logout'  => 'sessions#destroy'
      resources :users
    end

If somebody could point me in the right direction that would be fantastic.

Rgrds David

where you have

 redirect_back_or user

just change to

if admin_user?  # typically this is helper 
  redirect_to admin_page # adjust to your app.. i.e. where you want to go
else
  redirect_back_or user
end

where admin_user? is defined something like this:

def admin_user?
  current_user && current_user.admin?    
  # assuming admin is the name of your boolean field.  
end

Typically admin_user? would be a helper defined in the same place/way as current_user

Like this Mitch

        def create
              user = User.find_by(email: params[:session][:email].downcase)
          if user && user.authenticate(params[:session][:password])
             log_in user
             params[:session][:remember_me] == '1' ? remember(user) : forget(user)
             #remember user
             #redirect_to user
             if admin_user 
               redirect_to_admin_page
             else 
               redirect_back_or user 
             end    
            # Log the user in and redirect to the user's show page.
          else
            # Create an error message
            flash.now[:danger] = 'Invalid email/password combination'
            render 'new'
          end
        end

It seems that you have undeclared function redirect_back_or in module SessionsHelper

Some related useful functions in module SessionsHelper to defined are:

def redirect_back_or(default)
    redirect_to(session[:return_to] || default)
    clear_return_to
end

def store_location
    session[:return_to] = request.fullpath
end 

def clear_return_to
    session[:return_to] = nil
end

You can use store_location to save current path and redirect user when he/she signing in.

In your case, it should look like this:

def redirect_back_or(default)
    if user.admin?
        redirect_to admin_page  # the page you want admin to redirect
    else
        redirect_to (session[:return_to] || default)
    end
end

In my sessions helper I have not defined the admin_user like so

       # Returns true if the given user is the current user.
      def current_user?(user)
        user == current_user
      end

      def admin_user?
          current_user && current_user.admin?    
      end


        # Redirects to stored location (or to the default).
      def redirect_back_or(default)
        redirect_to(session[:forwarding_url] || default)
        session.delete(:forwarding_url)
      end

My create method in my sessions controller looks like this now

  def create
              user = User.find_by(email: params[:session][:email].downcase)
          if user && user.authenticate(params[:session][:password])
             log_in user
             params[:session][:remember_me] == '1' ? remember(user) : forget(user)
             #remember user
             #redirect_to user
                 if admin_user 
                   redirect_to root_url
                 else 
                   redirect_back_or user   
                end
            # Log the user in and redirect to the user's show page.
            else 
            # Create an error message
            flash.now[:danger] = 'Invalid email/password combination'
            render 'new'
          end
        end

However I'm getting the following error when I attempt to login

NameError in SessionsController#create undefined local variable or method `admin_user' for #

you could have something like

def admin_user
      redirect_to(root_url, status: :see_other) unless current_user.admin?
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM