This is an update of an old post of similar name but for a newer version of Devise and with better design decisions. The old post was for Devise 1.0.8, this one covers 4.0.0

I was trying to have a single page with both sign in and sign up forms with Devise 4.0.0 but this applies to whenever you want to show log in or registering individually or together anywhere on your site other than the views and controllers Devise creates for you.

For my task, I created a custom controller for it with a single new action as the create actions would be in the respective already existing Devise controllers. Something like this:

class Users::SessionsOrRegistrationsController < ApplicationController
  def new
  end
end

And then I created a new.html.erb (actually, new.html.haml, but I digress) that contained both log in and sign up one after the other. Something like this:


<h2>Sign up</h2>


<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
 <%= devise_error_messages! %>


<div class="field">
 <%= f.label :email %>
 <%= f.email_field :email, autofocus: true %>
 </div>



<div class="field">
 <%= f.label :password %>
 <% if @minimum_password_length %>
 <em>(<%= @minimum_password_length %> characters minimum)</em>
 <% end %>
 <%= f.password_field :password, autocomplete: "off" %>
 </div>



<div class="field">
 <%= f.label :password_confirmation %>
 <%= f.password_field :password_confirmation, autocomplete: "off" %>
 </div>



<div class="actions">
 <%= f.submit "Sign up" %>
 </div>

<% end %>

<hr/>


<h2>Log in</h2>


<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>

<div class="field">
    <%= f.label :email %>
    <%= f.email_field :email, autofocus: true %>
  </div>



<div class="field">
    <%= f.label :password %>
    <%= f.password_field :password, autocomplete: "off" %>
  </div>


  <% if devise_mapping.rememberable? -%>

<div class="field">
      <%= f.check_box :remember_me %>
      <%= f.label :remember_me %>
    </div>

  <% end -%>


<div class="actions">
    <%= f.submit "Log in" %>
  </div>

<% end %>

I actually ended up creating two _form partials and including them. In either case, when you try to render those views, you’ll get errors about some missing methods. You need to provide those as helper methods so my controller actually looks like this:

class Users::SessionsOrRegistrationsController < ApplicationController
  def new
  end

  private

  def resource_name
    :user
  end
  helper_method :resource_name

  def resource
    @resource ||= User.new
  end
  helper_method :resource

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
  helper_method :devise_mapping

  def resource_class
    User
  end
  helper_method :resource_class
end

And now it works.


9 responses to “Show a devise log in or sign up forms in another page”

  1. Michiel Avatar
    Michiel

    Where do you put the view and the controller so they work together?

    1. J. Pablo Fernández Avatar

      A controller with the name Users::SessionsOrRegistrationsController should go into app/controllers/users/sessions_or_registrations_controller.rb and the views should go into app/views/users/sessions_or_registrations.

  2. Michiel Avatar
    Michiel

    Thanks for the quick reply. It finds the view. I did a copy paste of your controller in a new controllers/users folder. It keeps on giving me “undefined local variable or method `resource’ for #<#”. Seems not to be picking up on the controller. It’s about checking out an order. Should I first prime something in the orders_controller?

    1. J. Pablo Fernández Avatar

      Anyone to help you would need to see all the relevant source code. Why don’t you post a question in Stack Overflow with it? Feel free to link it here and I’ll take a look.

  3. Osazeme Usen Avatar

    Will you have to add new routes to make this work?

  4. Lucas Avatar

    Do you have a sample implementation of this? I am trying to use this feature in an app, where I import the app/views/sessions/new.html.erb as a partial into another view in app/views/homepage/index.html.erb but am receiving an error: “undefined method `session_path’”

  5. whichwordshouldipress Avatar

    Do you have a sample implementation of this? I am trying to use this feature in an app, where I import the app/views/sessions/new.html.erb as a partial into another view in app/views/homepage/index.html.erb but am receiving an error: “undefined method `session_path’”

  6. Murtaza Avatar
    Murtaza

    can you suggest something for update password? Or posted something like that.? if yes plz share the link with me. Thanks

  7. Chuck Smith 💻 🇺🇦 (@EclecticCoding) Avatar

    This worked brillantly. Thanks for posting, it was the missing piece for me to create the combined forms on one page

Leave a Reply

You may also like:

If you want to work with me or hire me? Contact me

You can follow me or connect with me:

Or get new content delivered directly to your inbox.

Join 5,043 other subscribers

I wrote a book:

Stack of copies of How to Hire and Manage Remote Teams

How to Hire and Manage Remote Teams, where I distill all the techniques I've been using to build and manage distributed teams for the past 10 years.

I write about:

announcement blogging book book review book reviews books building Sano Business C# Clojure ClojureScript Common Lisp database Debian Esperanto Git ham radio history idea Java Kubuntu Lisp management Non-Fiction OpenID programming Python Radio Society of Great Britain Rails rant re-frame release Ruby Ruby on Rails Sano science science fiction security self-help Star Trek technology Ubuntu web Windows WordPress

I've been writing for a while:

Mastodon

%d bloggers like this: