I am a beginner in Ruby on Rails and just started to learn through youtube videos. I am trying to create a registration page.
Routes.rb:
Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# get "/about" request, pass to about controller and perform index action(function)
get "/about", to: "about#index", as: :about
get "/sign_up", to: "registration#new"
post "/sign_up", to: "registration#create"
root "main#index"
end
Sign_up.html.erb
<h1 >Sign Up</h1>
<%= form_with model: @user, url: sign_up_path do |form| %>
<div >
<%= form.label :email %>
<%= form.text_field :email, class:"form-control", placeholder: "[email protected]" %>
</div>
<div >
<%= form.label :password %>
<%= form.password_field :password, class:"form-control", placeholder: "password" %>
</div>
<div >
<%= form.label :password_confirmation %>
<%= form.password_field :password_confirmation, class:"form-control", placeholder: "password" %>
</div>
<div >
<%= form.submit class: "btn btn-primary" %>
</div>
<% end %>
controller.rb
class RegistrationController < ApplicationController
def new
# Since User model is created, this will look into database and create new instance on it
# Instance variable is used because it can be accessed in the view folder
@user = User.new
end
def create
# render plain: "Thanks"
render :create
end
end
create.html.erb
<h1>Thanks!</h1>
Console/Terminal:
Started POST "/sign_up" for ::1 at 2022-06-19 02:54:23 0800
Processing by RegistrationController#create as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create User"}
Rendering layout layouts/application.html.erb
Rendering registration/create.html.erb within layouts/application
Rendered registration/create.html.erb within layouts/application (Duration: 0.2ms | Allocations: 15)
Rendered shared/_navbar.html.erb (Duration: 0.2ms | Allocations: 125)
Rendered shared/_flash.html.erb (Duration: 0.1ms | Allocations: 28)
Rendered layout layouts/application.html.erb (Duration: 4.5ms | Allocations: 2465)
Completed 200 OK in 6ms (Views: 5.3ms | ActiveRecord: 0.0ms | Allocations: 2921)
Everything is good until I press the submit button of the form, it should have post request and the action should handle by the create which will render to create.html, from the console, it state that seems create.html is rendered but the browser still remain in the sign up page. I expect it to render to create.html after the form is submitted. Btw, I cant even render the plain in create method which I just comment out. Any idea? Thx.
Updates from Stefanyuk Yuriy's answer: First of all, thx for the reply, however, I rendered a blank page only with navbar after I submit the form, "Thanks!" did not show up in the browser.
Console/Terminal after submit form:
Started POST "/sign_up" for ::1 at 2022-06-19 10:15:24 0800
Processing by RegistrationController#create as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create User"}
Rendering registration/create.html.erb
Rendered registration/_thank.html.erb (Duration: 0.5ms | Allocations: 108)
Rendered registration/create.html.erb (Duration: 1.8ms | Allocations: 379)
Completed 200 OK in 4ms (Views: 2.4ms | ActiveRecord: 0.0ms | Allocations: 918)
Currently I am not sure where is the problem, any idea?
CodePudding user response:
First of all move your form to the partial app/views/registration/_form.html.erb
. Also move Thank you snippet
to the partial also and add create.turbo_stream.erb
file with content shown below. Wrap your form into turbo_frame_tag
. And change your controller as shown below:
# app/views/registration/_form.html.erb
<h1 >Sign Up</h1>
<%= form_with model: user, url: sign_up_path do |form| %>
<div >
<%= form.label :email %>
<%= form.text_field :email, class:"form-control", placeholder: "[email protected]" %>
</div>
<div >
<%= form.label :password %>
<%= form.password_field :password, class:"form-control", placeholder: "password" %>
</div>
<div >
<%= form.label :password_confirmation %>
<%= form.password_field :password_confirmation, class:"form-control", placeholder: "password" %>
</div>
<div >
<%= form.submit class: "btn btn-primary" %>
</div>
<% end %>
# app/views/registration/_thank.html.erb
<h1>Thanks!</h1>
# app/views/registration/new.html.erb
<%= turbo_frame_tag :sign_up_form do %>
<%= render 'form', user: @user %>
<% end %>
# app/views/registration/create.turbo_stream.erb
<% if @user.errors.any? %>
<%= turbo_stream.replace(:sign_up_form, partial: 'registration/form', locals: { user: @user }) %>
<% else %>
<%= turbo_stream.replace(:sign_up_form, partial: 'registration/thank_you') %>
<% end %>
class RegistrationController < ApplicationController
def new
@user = User.new
end
def create
@user = User.create(user_params)
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
Note: If you don't have save
logic yet just comment out @user = User.create(user_params)
and replace all code in app/views/registration/create.turbo_stream.erb
to
<%= turbo_stream.replace(:sign_up_form, partial: 'registration/thank_you') %>