Ganesh Kumar
Ganesh Kumar

Reputation: 1651

Validation failed: Email can't be blank, Password can't be blank

I am getting this error Validation failed: Email can't be blank, Password can't be blank when i try to do signup. i am using devise's custom registration controller for sign up. i am using the model employee in place of user.

The custom registration_controller.rb

class RegistrationsController < Devise::RegistrationsController

  def new
    @employee = Employee.new
    @organisation = Organisation.new
    getLocation
  end

  def create
    @organisation = Organisation.new
    setOrganizationValues
    @employee = Employee.new
    setEmployeeValues

    Employee.transaction do
        @organisation.save!

        @employee.org_id = @organisation.org_id
        @employee.save!
    end

    respond_to do |f|
      f.html {redirect_to employees_path}
    end
        # if @employee.save
        #   flash[:notice] = "Employee was successfully created"
        #   redirect_to employees_path
        # else
        #   flash[:notice] = "Employee was not created"
        # end
  end

  def getLocation
    @locations = Location.select("location_id, location_name")
                                .where("status = 1")
                                .order("location_name")
  end

  def setCountryName
    loc = Location.select("location_name")
                                .where("location_id = ?",params[:country])
    @organisation.country = loc.first.location_name
  end

  def setOrganizationValues
    p "***********setOrganizationValues****************"
    @organisation.org_name = params["org_name"]
    @organisation.location_id = params["country"]
    @organisation.city = params["city"]
    @organisation.state = params["state"]
    @organisation.email_id = params["email_id"]
    @organisation.address = params["address"]
    setCountryName
  end

  def setEmployeeValues
    p "***********setEmployeeValues****************"
    @employee.email = params["email"]
    @employee.password = params["password"]
    @employee.first_name = params["first_name"]
    @employee.middle_name = params["middle_name"]
    @employee.last_name = params["last_name"]
    # @employee.state = params["state"]
    # @employee.email_id = params["email_id"]
    # @employee.address = params["address"]
  end

end

routes.rb

Rails.application.routes.draw do
  # devise_for :employees, :controllers => { :registrations => "registrations" }, :path => "", :path_names => {:sign_out => "signout", :sign_up => "signup"}

  devise_for :employees, :controllers => {:registrations => "registrations"}

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root 'organisations#index'
  resources :organisations
  resources :roles
  resources :clients
  resources :project_tasks
  resources :projects
  resources :employees
  get '/projects', to: 'projects#index'
  get '/employees', to: 'employees#index'
end

The View new.html.erb

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), :html => {:id => "example-advanced-form"}) do |f| %>
<br><br>
    <h3>Account</h3>
    <fieldset>
        <legend>Account Information</legend>

        <%= f.label :email %><br>
        <%= f.text_field :email, :id => "email-2", :class => "required email" %>
        <%= f.label :password %><br>
        <%= f.password_field :password, :id => "password-2", :class => "required" %>
        <%= f.label :password_confirmation %><br>
        <%= f.password_field :password_confirmation, :name => "confirm", :id => "confirm-2", :class => "required" %>
        <p>(*) Mandatory</p>
    </fieldset>

    <h3>Profile</h3>
    <fieldset>
        <legend>Profile Information</legend>

        <div class="container-fluid">
          <div class="row">
            <div class="col-lg-6">

        <label>First Name</label><br>
        <%= text_field_tag "first_name",@employee.first_name,
                  :autocomplete => :off,:id => "name-2",:maxlength => 13,:required => true%>
        <label>Middle Name</label><br>
        <%= text_field_tag "middle_name",@employee.middle_name,
                  :autocomplete => :off,:id => "surname-2",:maxlength => 13,:required => true%>
        <label>Last Name</label><br>
        <%= text_field_tag "last_name",@employee.last_name,
                  :autocomplete => :off,:id => "surname-2",:maxlength => 13,:required => true%>

        <label>Designation</label><br>
        <select class="required">
          <option value="Developer">Developer</option>
          <option value="Tester">Tester</option>
          <option value="Manager">Manager</option>
          <option value="Other">Other</option>
        </select>
        <br>
          <label>Organisation Name</label><br>
          <%= text_field_tag "org_name",@organisation.org_name,
                                        :autocomplete => :off,:id => "phone",:maxlength => 13,:required => true%>
          <label>organisation Business Type</label><br>
          <select class="required">
            <option value="Business">Business</option>
            <option value="Finance">Finance</option>
            <option value="IT">IT</option>
            <option value="Other">Other</option>
          </select><br>
          </div>
          <div class="col-lg-6">
          <label>Number Of Employees</label><br>
          <select class="required">
            <option value="0-10">0-10</option>
            <option value="10-50">10-50</option>
            <option value="50-100">50-100</option>
            <option value="100-500">100-500</option>
            <option value="500-1000">500-1000</option>
            <option value="1000 above">1000 above</option>
          </select><br>

          <label>Address</label><br>
          <%= text_field_tag "address",@organisation.address,
                                        :autocomplete => :off,:id => "address",:required => true%>
          <label>City</label><br>
          <%= text_field_tag "city",@organisation.city,
                                        :autocomplete => :off,:id => "city",:required => true%>
          <label>State</label><br>
          <%= text_field_tag "state",@organisation.state,
                                        :autocomplete => :off,:id => "state",:required => true%>
          <label>Country</label><br>
          <!-- <%= text_field_tag "country",@organisation.country,
                                        :autocomplete => :off,:id => "country",:required => true%> -->
          <%= select_tag :country, options_for_select(@locations.collect{ |l| [l.location_name, l.location_id]})%>
          <label>Organisation Email</label><br>
          <%= text_field_tag "email_id",@organisation.email_id,
                                        :autocomplete => :off,:id => "email_id",:required => true%>


      </div>
      </div>
    </div>

    </fieldset>

    <h3>Finish</h3>
    <fieldset>
        <legend>Confirmatio</legend>

        <p>We have sent you a mail for Activation of your Account. Kindly Activate your through the mail. If you haven't received any mail, please click </p>
        <%= link_to "here" %>
    </fieldset>

<% end %>

<script>
var form = $("#example-advanced-form").show();

form.steps({
    headerTag: "h3",
    bodyTag: "fieldset",
    transitionEffect: "slideLeft",
    onStepChanging: function (event, currentIndex, newIndex)
    {
        // Allways allow previous action even if the current form is not valid!
        if (currentIndex > newIndex)
        {
            return true;
        }
        // Forbid next action on "Warning" step if the user is to young
        if (newIndex === 3 && Number($("#age-2").val()) < 18)
        {
            return false;
        }
        // Needed in some cases if the user went back (clean up)
        if (currentIndex < newIndex)
        {
            // To remove error styles
            form.find(".body:eq(" + newIndex + ") label.error").remove();
            form.find(".body:eq(" + newIndex + ") .error").removeClass("error");
        }
        form.validate().settings.ignore = ":disabled,:hidden";
        return form.valid();
    },
    onStepChanged: function (event, currentIndex, priorIndex)
    {
        // Used to skip the "Warning" step if the user is old enough.
        if (currentIndex === 2 && Number($("#age-2").val()) >= 18)
        {
            form.steps("next");
        }
        // Used to skip the "Warning" step if the user is old enough and wants to the previous step.
        if (currentIndex === 2 && priorIndex === 3)
        {
            form.steps("previous");
        }
    },
    onFinishing: function (event, currentIndex)
    {
        form.validate().settings.ignore = ":disabled";
        return form.valid();
    },
    onFinished: function (event, currentIndex)
    {
        form.submit();
        alert("Submitted!");
    }
}).validate({
    errorPlacement: function errorPlacement(error, element) { element.before(error); },
    rules: {
        confirm: {
            equalTo: "#password-2"
        }
    }
});
</script>

employee.rb

class Employee < ApplicationRecord

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_many :tasks
  belongs_to :organisation
  belongs_to :role
  accepts_nested_attributes_for :organisation
  validates :first_name, presence: true, length: { minimum: 5 }
  validates :last_name, presence: true, length: { minimum: 5 }
end

I am a newbie to rails. can anybody help me to solve this issue?

Upvotes: 0

Views: 2057

Answers (1)

Gavin Miller
Gavin Miller

Reputation: 43825

Looks like the trouble is in the code that sets the employee information.

def setEmployeeValues
  p "***********setEmployeeValues****************"
  @employee.email = params["email"]              # <= this should be params[:employee]["email"]
  @employee.password = params["password"]        # <= this should be params[:employee]["password"]
  @employee.first_name = params["first_name"]    # <= these lines below are ok
  @employee.middle_name = params["middle_name"]  #    since you haven't used f. for them
  @employee.last_name = params["last_name"]
end

Because you've declared your email, password and password_confirmation tags using the form instance f. these parameters are going to get wrapped in an employee hash. It will look like this:

params = {
  "employee" => {
    "email"    => <value>,
    "password" => <value>
  },
  "first_name"  => <value>,
  "middle_name" => <value>,
  "last_name"   => <value>
}

So when you do params[:email] in setEmployeeValues it's returning nil. Instead do params[:employee][:email], and the same for password.

If you look at your server logs it should be very clear what Parameters you'll have accessible in your controller.

Upvotes: 1

Related Questions