70

I am launching a beta site with a select group of users. I want to disable registration in the production environment only, and only for a short period of time (i.e. I don't want to nuke my registration altogether). I know I can simply hide the "sign up" link, but I suspect that hackers smarter than I can still use the RESTful routes to accomplish registrations. What's the best way to disable registration so my test/development environments still work, but production is affected? Thanks for any pointers.

I've tried pointing named scopes in such a way that "sign_up" goes to "sign_in", but it didn't work. Here's what I've tried:

devise_scope :user do
    get "users/sign_in", :to => "devise/sessions#new", :as => :sign_in
    get "users/sign_up", :to => "devise/sessions#new", :as => :sign_up
end

Ideally, we'd send the user to a "pages#registration_disabled" page or something like that. I just wanted to get something working I can play around with.

EDIT: I've changed the model as requested, then added the following to /spec/user_spec.rb

describe "validations" do
    it "should fail registration if in production mode" do
      ENV['RAILS_ENV'] = "production"
      @user = Factory(:user).should_not be_valid
    end
end

it is passing as "true" rather than false. Is there a way to mock up the production environment? I'm just spit-balling this one.

Thanks!

panzhuli
  • 2,890
  • 6
  • 33
  • 46

4 Answers4

103

Edit the user model and remove :registerable, I think that should give you what you want.

Edit:

I think this would work:

if Rails.env.production?
  devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
else
  devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :registerable 
end
Fareesh Vijayarangam
  • 5,037
  • 4
  • 23
  • 18
  • That would remove for all environments tho, right? is there a way to specify by environment at the model level? – panzhuli Mar 20 '11 at 19:21
  • 7
    Didn't need this, but discovered I could use "Rails.env" in models. Priceless :) Thanks. – vvohra87 Nov 29 '11 at 22:07
  • 8
    As per Chris Nicola's answer http://stackoverflow.com/a/8291318/9344, this will disable the ability to editing registrations which is probably more than the desired effect (definitely was in my case). – Ted Nov 07 '12 at 18:06
  • How to disable /users/sign_in under production? – W.M. Sep 13 '17 at 08:20
88

Since others are having the problem I'm having (see my comments). Here is exactly how I fixed it. I used murphyslaw's idea. But you also need to make sure devise uses your new controller for the registration routing, or it won't do much for you.

Here is my controller override:

class RegistrationsController < Devise::RegistrationsController
  def new
    flash[:info] = 'Registrations are not open yet, but please check back soon'
    redirect_to root_path
  end

  def create
    flash[:info] = 'Registrations are not open yet, but please check back soon'
    redirect_to root_path
  end
end

I've added flash messages to inform anyone who somehow stumbles upon the registration page why it isn't working.

Here is what is in my routes.rb

  if Rails.env.production?
    devise_for :users, :controllers => { :registrations => "registrations" } 
  else
    devise_for :users
  end

The controllers hash specifies that I want it to use my overridden registrations controller.

Anyways, I hope that saves someone some time.

Chris Nicola
  • 14,384
  • 6
  • 47
  • 61
11

Only remove :registerable will not solve the problem. If you have some routes in your view you will get an error:

undefined local variable or method 'edit_user_registration_path'

Take care of this.

Mindbreaker
  • 1,015
  • 1
  • 9
  • 23
6

you could override the Devise::RegistrationsController and the create action to redirect to the page you want. The Controller should probably look something like this:

class User::RegistrationsController < Devise::RegistrationsController

  def create
    redirect_to your_page_path if Rails.env.production?
  end

end
murphyslaw
  • 640
  • 5
  • 12
  • 1
    This is important, since disabling :registerable breaks both edit and create registration routes. So if you are testing in production with users you have already created disabling :registrable can cause a bunch of problems – Chris Nicola Nov 28 '11 at 02:29
  • Exactly. I actually had to kill my register route for production. i'll give this a try as I rebuild some of the core features of my site. Thanks! – panzhuli Nov 28 '11 at 03:18
  • Be sure to call `super` in case this is not production. – Sunny Mar 20 '21 at 16:10