Petros Kyriakou
Petros Kyriakou

Reputation: 5343

Redirect loop when using before_filter in rails 4.2

Hello guys so what i want to do is simple.

I want a before filter to check if the current user is admin, to automatically redirect him to the admin panel even if the admin accesses the index page(e.g localhost:3000 which is the root url for normal users)

for the admin users the path is localhost:3000/admin/

I have written these blocks of code so far but cause a redirect loop

in my application_controller.rb i have this

include SessionsHelper
before_filter :admin_users?


  private
    def admin_users?
      if current_user.admin?
        redirect_to admin_path
      end
    end

and the current_user method is the following which is in sessionshelper.rb

  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?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

here is users controller

class UsersController < ApplicationController

  before_filter :admin_users? # application controller method

  before_action :logged_in_user, only: [:index,:edit,:update] # is in Application Controller
  before_action :correct_user, only: [:edit,:update]
  before_action :admin_user, only: :destroy


  def index
    @users = User.paginate(page: params[:page])
  end

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

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      @user.send_activation_email
      flash[:info] = "Please check your email to activate your account."
      redirect_to root_url
    else
      render 'new'
    end
  end

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

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

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted"
    redirect_to users_url
  end


  private

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

    # before filters


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

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end

end

any clues?

Upvotes: 1

Views: 1067

Answers (1)

Nermin
Nermin

Reputation: 6100

The issue is next. You have put your redirect inside application_controller.rb, that all other controller inherit from, even Admin controller.

You have to do next:

remove before_filter :admin_user from your ApplicationController, and put it only where you want to check if user is admin, all controllers except admin controller.

You have redirect loop because admin controller will redirect to admin_path, when you come to admin_path.

Upvotes: 1

Related Questions