Specify a different root path for logged in users

2019-09-14 15:54发布

问题:

If the user is logged in, I want users#show to be the route path. Else, the route path should be static_pages#home.

Please let me know how I can achieve this without using the Devise gem.

回答1:

I think having if/else statements in your routes file isn't right. Think of it as a business logic in your routes files. You business logic should be in your Models (not necessarily an ActiveRecord, just any plain old ruby class would do) or if it better fits in your controller (like in this case) in your controller.

Supposed you are not using any middleware like warden to do user authentication, you would have to do database queries and authentication right in your routes file. This should be another flag that it does not belong there. As an analogy, it is like doing SQL queries in your views.


Alright, I hope justified my opinion. Now, let's get back to a possible solution.

Set a root path to some controller action where you would do if/else check and redirect to correct path.

# routes.rb
root 'static_pages#home'

# StaticPagesController.rb
before_filter :redirect_if_logged_in

def redirect_if_logged_in
    redirect_to(user_path(@user)) if @user # check if user logged in
end

Or do similar in users#show action. Whichever suits your case best.



回答2:

In order to do this, you'd probably need to define a constraint, the most important method here is the matches? as such

# in constraints/homepage_constraint.rb
class HomepageConstraint
  def matches?(request)
   # in most cases, you'd store your user_id or other params for determining the current user in a session
   request.session[:user_id].present?
  end
end


routes.rb
# Rails route is based on the order, place the constraint here to check if there is a current user, if the `matches?` returns false, it would use the generic root route
root 'users#show', constraints: HomepageConstraint.new
root 'static_pages#home'