Home > other >  Rails - errors partial not rendering
Rails - errors partial not rendering

Time:02-15

I'm very new to Rails and full-stack development in general. I've just finished Michael Hartl's Ruby on Rails Tutorial 6th edition and am walking through it again to build my first project (i.e. an app that's different from the sample app built in the book, but draws on a lot of the same lessons). Catch is that new project is using Rails 7.

It was going well until I ran into issues around Chapter 7; my app will not render a partial with error messages for bad submissions to the new user form. The code in the partial executes (as verified with debugger, and later with a puts statement to output on console), but the HTML doesn't output (i.e. it cannot be found when inspecting the page in Chrome). There is a CSS issue related to newer version of bootstrap, but I even tried downgrading to the bootstrap version from the book (3.4.1) with no luck. (the offending CSS segment is commented out below)

I've banged my head on this for a few hours. Hoping it's just something dumb I'm missing. If it's a broader issue with Bootstrap vs Importmaps or something I'd also appreciate references on good places to learn these. I am extremely grateful for any ideas!

app/views/users/new.html.erb:

<% provide(:title, 'Create New User') %>
<h1>Create New User</h1>

<div >
    <div >

        <%= form_with(model: @user, local: true) do |f| %>
            <%= render 'shared/error_messages' %>
            
            <%= f.label :email %>* <i>required</i>
            <%= f.email_field :email %>      

            <%= f.label :first_name %>
            <%= f.text_field :first_name %>
            
            <%= f.label :last_name %>
            <%= f.text_field :last_name %>
            
            <%= f.label :phone_number %>
            <%= f.text_field :phone_number %>
            
            <% # f.label :admin, "Company Admin" %> 
            <% # f.radio_button :admin, "True" %> 
            <% # f.label :admin, "Regular User" %>
            <% # f.radio_button :admin, "False", :checked => true %> 
            
            
            <%= f.submit "Create New User", class: "btn btn-primary" %>
        <% end %>
    </div>
</div>

app/views/shared/_error_messages.html.erb:

<% if @user.errors.any? %>
  <% puts "the error partial was called" %>
  <div id="error_explanation">
    <div >
      The form contains <%= pluralize(@user.errors.count, "error") %>
    </div>
    <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

Example server output when submitting bad data that should generate an error (fail email validation):

 Started POST "/users" for 24.85.170.222 at 2022-02-14 01:01:56  0000
Cannot render console from 24.85.170.222! Allowed networks: 127.0.0.0/127.255.255.255, ::1
Processing by UsersController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"no123@good-email", "first_name"=>"Jeff", "last_name"=>"Lebowski", "phone_number"=>""}, "commit"=>"Create New User"}
   (0.1ms)  SELECT sqlite_version(*)
  ↳ app/controllers/users_controller.rb:13:in `create'
  TRANSACTION (0.1ms)  begin transaction
  ↳ app/controllers/users_controller.rb:13:in `create'
  User Exists? (0.2ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "no123@good-email"], ["LIMIT", 1]]
  ↳ app/controllers/users_controller.rb:13:in `create'
  TRANSACTION (0.1ms)  rollback transaction
  ↳ app/controllers/users_controller.rb:13:in `create'
  Rendering layout layouts/application.html.erb
  Rendering users/new.html.erb within layouts/application
the error partial was called
  Rendered shared/_error_messages.html.erb (Duration: 1.8ms | Allocations: 701)
  Rendered users/new.html.erb within layouts/application (Duration: 6.2ms | Allocations: 2949)
  Rendered layouts/_rails_default.html.erb (Duration: 6.7ms | Allocations: 6277)
  Rendered layouts/_shim.html.erb (Duration: 0.5ms | Allocations: 153)
  Rendered layouts/_header.html.erb (Duration: 0.8ms | Allocations: 318)
  Rendered layouts/_footer.html.erb (Duration: 0.8ms | Allocations: 258)
  Rendered layout layouts/application.html.erb (Duration: 18.8ms | Allocations: 11238)
Completed 200 OK in 35ms (Views: 23.0ms | ActiveRecord: 0.8ms | Allocations: 16412)

Gemfile:

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.0.3"

gem "rails", "~> 7.0.1"   
gem "sprockets-rails"
gem "puma", "~> 5.0"
gem "importmap-rails"
gem "turbo-rails"           # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "stimulus-rails"        # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "jbuilder"              # Build JSON APIs with ease [https://github.com/rails/jbuilder]


gem "bootsnap", require: false
gem "sassc-rails"           # Use Sass to process CSS 

gem 'image_processing'#,           '1.9.3'
gem 'mini_magick'#,                '4.9.5'
gem 'active_storage_validations'#, '0.8.9'
gem 'bcrypt'#,                     '3.1.13'
gem 'faker'#,                      '2.11.0'
gem 'will_paginate'#,              '3.3.0'
gem 'bootstrap-will_paginate'#,    '1.0.0'
gem 'bootstrap-sass'#,             '3.4.1'

group :development, :test do
  gem "sqlite3", "~> 1.4" 
  gem "debug", platforms: %i[ mri mingw x64_mingw ] 
end

group :development do
  gem "web-console"     
  gem "rack-mini-profiler"   
  gem "spring"              
end

group :test do
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
  gem "capybara"
  gem "selenium-webdriver"
  gem "webdrivers"
  
  gem 'rails-controller-testing'#, '1.0.5'
  gem 'minitest'#,                 '5.11.3'
  gem 'minitest-reporters'#,       '1.3.8'
  gem 'guard'#,                    '2.16.2'
  gem 'guard-minitest'#,           '2.4.6'
end

group :production do
  gem "pg"
  gem 'aws-sdk-s3', require: false
end

app/assets/stylesheets/custom.scss:

@import "bootstrap-sprockets";
@import "bootstrap";

/* mixins, variables, etc. */

$gray-medium-light: #eaeaea;

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

@mixin box_sizing {
  -moz-box-sizing:    border-box;
  -webkit-box-sizing: border-box;
  box-sizing:         border-box;
}


/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: $gray-light;

}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}

/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: white;
  /* text-transform: uppercase; */
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  &:hover {
    color: white;
    text-decoration: none;
  }
}

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: $gray-light;
  a {
    color: $gray;
    &:hover {
      color: $gray-darker;
    }
  }
  small {
    float: left;
  }
  
}


footer ul {
  float: right;
  list-style: none;
}

footer ul li {
  float: left;
  margin-left: 15px;
}

/* Forms */

input, textarea, select, .uneditable-input {
  border: 1px solid #bbb;
  width: 100%;
  margin-bottom: 15px;
  @include box_sizing
}

input {
  height: auto !important;
}

#error_explanation {
  color: red;
  ul {
    color: red;
    margin: 0 0 30px 0;
  }
}

/*
.field_with_errors {
  @extend .has-error;    /*this is breaking 
  /*potential solution? https://jasoncharnes.com/bootstrap-4-rails-fields-with-errors/
  .form_control {
    
    color: $state-danger-text;
  }
}
*/ 

/* Miscellaneous */

.debug_dump {
  clear:       both;
  float:       left;
  width:       100%;
  margin-top:  45px;
  @include box_sizing;
}

app/controllers/users_controller.rb:

class UsersController < ApplicationController
  def new
    @user = User.new
  end
  
  def show
    @user = User.find(params[:id])
  end
  
  def create
    @user = User.new(user_params)   #strong params required by Rails
    #debugger
    if @user.save
      #handle succesful save
    else
      render 'new'
    end
  end
  
  private
  
    def user_params
      params.require(:user).permit(:email, :first_name, :last_name, :phone_number, :admin)
    end
end

CodePudding user response:

Try this in app/views/users/new.html.erb

<%= render 'shared/error_messages', user: @user %>

If it's a shared partial, maybe make the instance variable generic rather than @user also. That way it can be reused and less confusing later.

CodePudding user response:

Use locals on your render:

render 'shared/error_messages', locals: { user: @user }

And on shared/error_messages rename @user by user.

  • Related