Skip to content

How To: Set up devise as a single user system

Philippe AKA edited this page Dec 21, 2015 · 8 revisions
Clone this wiki locally

Rationale: Some projects might come across the need for an authentication solution to which devise is supremely suited for -- but without the need (or want) to have public viewers trying to register.

The example of a private weblog comes to mind, so we will use it as an example. This, along with How to: add an admin role (Especially using Option 2 of just using an :admin attribute), and lastly How To: Restrict access to specific actions gives a pretty robust authentication and authorization abilities to your app/website in mere minutes.

In order to implement our single user registration system, we are going to:

  • Override the registration controller of Devise (Step 1)
  • Add a method before the registration page is rendered (Step 2). This method will check if one user is already registered. The user will be redirected to the home page or sign in page if the application has one user. If the application has no user, the registration page will be rendered.

Step 1:

Alter the devise_for line in config/routes.rb to override the registration controller:

devise_for :users, controllers: { registrations: "registrations"}

Step 2

app/controllers/registrations_controller.rb:

class RegistrationsController < Devise::RegistrationsController

  before_action :one_user_registered?

  protected

  def one_user_registered?
    if ((User.count == 1) & (user_signed_in?))
      redirect_to root_path
    elsif User.count == 1
      redirect_to new_user_session_path
    end  
  end

end

That's it

The /users/sign_in path still gives you a login form, and /users/sign_out still logs you out.

You can add this to your application.html.erb to make some quick and easy links:

<% if user_signed_in? %>
   <%= link_to('logout', method: :delete, destroy_user_session_path) %>
<% else %>
  <%= link_to('login', new_user_session_path) %>
<% end %>
Something went wrong with that request. Please try again.