0
votes

I am naive in ROR. I am trying to login user with only email, using devise. I want to render login page if user with email provided does not exist. But, when I try to render 'new', after checking that user does not exist in database. While doing so I get error - "First argument in form cannot contain nil or be empty". Please help me out on this. Thanks in advance !!!

rails/app/controllers/users/sessions_controller.rb

# frozen_string_literal: true

# Users sessions controller
class Users::SessionsController < Devise::SessionsController
  include ExpireExistingToken
  
  layout 'devise'

  def new
    super
  end

  def create
    # self.resource = warden.authenticate!(auth_options)
    self.resource = User.find_by(email: params[:user][:email])
    if resource.nil?
      render 'new'
    else
      set_flash_message!(:notice, :signed_in)
      sign_in(resource_name, resource)
      yield resource if block_given?
      resource.update(language: Constant::SUPPORTED_LANGUAGES.key(params['locale'])) if params['locale'].present?
      resource.send_otp(force_expire: true) if resource.email_verified?
      respond_with resource, location: after_sign_in_path_for(resource)
      flash.delete(:notice)
    end  
  end

  def destroy
    session.delete(:is_otp_verified)
    super
  end
end

rails/app/controllers/concerns/expire_existing_token.rb

# frozen_string_literal: true

# Responsible for token expiration
module ExpireExistingToken
  extend ActiveSupport::Concern

  included do
    before_action :remove_existing_token, only: :new
  end

  protected

  def remove_existing_token
    uuid = session[:uuid]
    usr = User.find_by(uuid: uuid) if uuid
    return unless usr
    usr.send(:clear_reset_password_token)
    usr.save
    session.delete(:uuid)
  end
end

rails/app/views/devise/sessions/new.html.haml

.authentication-wrapper
  .gatway
    .brand-icon
      = image_pack_tag('packs/images/logo.png')
    .title
      Merchant Login
    .caption
      Make every moment special with WadzPay.
    = form_for(resource, as: resource_name, url: session_path(resource_name),
      html: { class: 'user-session-form new_user' }) do |f|
      .form-group
        = f.email_field :email, placeholder: 'Enter Email Address',
                                                type: 'email', class: 'form-control'
        %span
          = image_pack_tag('packs/images/mail.svg')
      .auth-btn-set
        = f.button 'Log in', class: 'btn-primery-grdient w-100'
        %a.btn-white-link.w-100{href: "register.html"} Register
  .auth-footer
    %a{href: "#"} Terms &amp; Condition
    |
    %a{href: "#"} Privacy Policy

3

3 Answers

0
votes

The new view display a form for the current resource, which should be initialized in the action new.

Your best bet at this point, is to replace render 'new' by calling new itself, which should take care of your problem.

0
votes

Using render 'new' will make your application load the new html, what you want in this case is to redirect your user to the registrations page. Replacing render 'new' for redirect_to action: :new should do the trick.

0
votes

"render" only renders the template but if you want to gain the object access to perform some operation then "redirect_to" comes in picture.

So simply replace render: new to redirect_to: new