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
.