I have a rails app that uses the Clearance for signup and login. After signup the user is redirected to accounts/new
to complete their account setup. The Account belongs_to
User and the user has_one
account. (The Account and User models are separate because there are attributes, such as "Company Name" that I don't want to put into the User model.)
I'd like to lock down everything in the application and redirect them to accounts/new
if they try to access anything other than marketing pages, signup, and login pages before they've created an Account.
I'm thinking that adding a before_action
to the ApplicationController is the right approach and then using :skip_before_action
on any controller#action
that they need access before creating their Account (such as /signup or /login or marketing pages).
This seems like the right approach since the entire application will be locked down by default if the User hasn't created an account. By explicitly using using :skip_before_action
as needed it seems like there is less of a chance of creating holes in the application by mistake.
But I can't get the before_action
on the ApplicationController to work because I keep getting this error when I visit a page like /signup:
NoMethodError in Clearance::UsersController#new
undefined method `account' for nil:NilClass
I'm trying to do something like this:
class ApplicationController < ActionController::Base
include Clearance::Controller
before_action :require_login
before_action :require_account
private
def require_account
if current_user.account != nil
redirect_to dashboard_path
end
end
end
That syntax worked when I was inside my AccountsController and just redirecting my accounts#new
action, but now I'm having trouble figuring out how to get the same behavior across my entire application. Note: current_user
is a method supplied by Clearance.
What is the "Rails way" to do this?
If I understood correctly, I consider you're in the right way to do it in 'Ruby on Rails way'!
The error NoMethodError
is caused because inside some contexts of your application you don't have the current_user
method.
If you want to redirect the user to dashboard_path
when the current_user already have the account, you should try the following:
class ApplicationController < ActionController::Base
include Clearance::Controller
before_action :require_login
before_action :require_account
private
def require_account
if current_user && current_user.account.present?
redirect_to dashboard_path
end
end
end
This way you can get the redirect when current_user is present
AND current_user have one account
, no skip_before_action
is needed.