This is a quick and dirty solution, just creates a user with the given credentials when no user exists in the database. In login_controller.rb:
def login session[:user_id] = nil if request.post? if User.count.zero? user = User.create(:name => params[:name], :password => params[:password], :password_confirmation => params[:password]) else user = User.authenticate(params[:name], params[:password]) end if user session[:user_id] = user.id uri = session[:original_uri] session[:original_uri] = nil redirect_to(uri || { :action => "index" }) else flash[:notice] = "Invalid user/password combination" end end end
Cosmin Lehene:
This will pass over authorize method like a valid login as long as no users are created in the database and will flash a warning notice permanently. After the first user is created it will ask for credentials.
In application.rb change the authorize method:
def authorize unless User.find_by_id(session[:user_id]) or User.count == 0 session[:original_uri] = request.request_uri flash[:notice] = "Please login" redirect_to(:controller => "login", :action => "login") end if User.count == 0 flash[:notice] = "Please create the first user account" end end end
Of course, in order to get the required behavior, you have to modify the login action in login_controller.rb also:
def login session[:user_id] = nil if User.count == 0 redirect_to(:action => "add_user") elsif [...]
k9d says:
I followed Cosmin's example except I wanted the user to be redirect to the page where they can create the first user account. To achieve this I modified def authorize in application.rb to look more like this
#... if User.count == 0 flash[:notice] = "Please create the first user account" redirect_to(:controller => "login", :action => "add_user") end #...
All is well except the before_filter in login_controller.rb doesn't allow the un-authorized user to see add_user. Is there a way to work around this problem?
Also, a handy mysql command if you need to manually clear out the last user, to "Delete a row(s) from a table":
DELETE from [table name] where [field name] = 'whatever';
Matt says:
To allow an unauthorised user to get to the add_user page, check the path_parameters of the request:
def authorize unless User.find_by_id(session[:user_id]) or User.count == 0 session[:original_uri] = request.request_uri flash[:notice] = "Please log in." redirect_to(:controller=>"login", :action=>"login") end if User.count == 0 if request.path_parameters[:action]=="add_user" and request.path_parameters[:controller]=="login" #As we are already on our way to the add_user action, do nothing here. else flash[:notice] = "Please create an account." redirect_to(:controller=>"login", :action=>"add_user") end end end
jwat says:
Matt's code worked for me. However, as good programming practice, it makes more sense to write the logic for zero user counts as so:
def authorize unless User.find_by_id(session[:user_id]) or User.count == 0 session[:original_uri] = request.request_uri flash[:notice] = "Please log in." redirect_to(:controller=>"login", :action=>"login") end if (User.count == 0 and request.path_parameters['action'] != "add_user") flash[:notice] = "Please create an account." redirect_to(:controller=>"login", :action=>"add_user") end end
I suppose you can check for the controller params as well, but I didn't bother.