1

I'm new to rails so I have a Signup controller that looks as follows:

class SignupController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to root_path, notice: "You are logged in as #{@user[:username]}"
    else
      puts @user.errors.full_messages
      render :new
    end
  end

  private
  def user_params
    puts params
    params.require(:user).permit(:email, :password, :password_confirmation, :username)
  end
end

So I'm trying to create a new user when I submit the form and my routes.rb file contains the following:

Rails.application.routes.draw do
  root to: "home#index"
  get '/about-us', to: "about#index", as: :about

  # signing up
  get 'sign_up', to: "signup#new"
  post 'sign_up', to: "signup#create"

end

My app/views/signup/new.html.erb file has the following code in it:

<h1>Sign Up</h1>
<%= form_with model: @user, url: sign_up_path do |form| %>
    <%= @user.errors.full_messages.inspect %>
    <% if @user.errors.any? %>
     <div class="alert alert-danger">
        <% @user.errors.full_messages.each do |message| %>
            <div><%= message %></div>
        <% end %>
     </div>
    <% end %>
   <div class="mb-3">
        <%= form.label :email, class: "form-label"%>
        <%= form.text_field :email, placeholder: "email@gmail.com", class: "form-control"%>
    </div>
    <div class="mb-3">
        <%= form.label :username, class: "form-label"%>
        <%= form.text_field :username, placeholder: "username", class: "form-control"%>
    </div>
    <div class="mb-3">
        <%= form.label :password, class: "form-label"%>
        <%= form.password_field :password, placeholder: "password", class: "form-control"%>
    <div class="mb-3">
        <%= form.label :password_confirmation, class: "form-label"%>
        <%= form.password_field :password_confirmation, placeholder: "password", class: "form-control"%>
    </div>
    <div class="mb-3">
        <%= form.submit "Sign Up", class: 'btn btn-primary'%>
    </div>
<% end %>

But it seems like I'm getting the error messages in the console but they can't be rendered in the template when i submit the form with errors. Here is the errors i'm getting:

Password can't be blank
Email can't be blank
Email invalid email address
Username can't be blank

What maybe possibly the problem with my code here.

crispengari
  • 7,901
  • 7
  • 45
  • 53
  • There is no obvious error here. We could possibly help you a bit more if you showed the logs and tell us actual steps that lead to this unexpected behavior. If I were you I would write tests for the happy path (with valid input) and when the user submits invalid data. Then add it to the question - that gives us an exact set of repeatible steps and ensures that you don't get regressions later. Trust me - learning to test properly is time well spent. https://guides.rubyonrails.org/testing.html#system-testing – max Feb 17 '23 at 12:54
  • You'll also want to learn to use `debug` and set breakpoints instead of using `puts`. https://github.com/ruby/debug – max Feb 17 '23 at 12:56
  • 1
    i assume you're using rails 7: https://stackoverflow.com/q/71751952/207090 – Alex Feb 17 '23 at 17:00
  • Might be that you are breaking the flow calling `render :new` and this sets the user to new one, losing the error messages. Try using `respond_to` instead render – anonymus_rex Feb 17 '23 at 17:52

2 Answers2

1

I was using rails version 7.* so I manage to solve this error by changing the create method in the SignupController to :

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to root_path, notice: "You are logged in as #{@user[:username]}"
    else
      puts @user.errors.full_messages
      render :new, status: :unprocessable_entity, content_type: "text/html"
    end
  end

This is according to the suggestions i got from Alex in the comments together with the discussion that i found here.

crispengari
  • 7,901
  • 7
  • 45
  • 53
0

In your form, try this instead

<% if @user.errors.any? %>
     <div class="alert alert-danger">
        <% @user.errors.each do |error| %>
            <div><%= error.full_message %></div>
        <% end %>
     </div>
<% end %>