Find out about Rails hidden_field (create a confirmation screen and check the behavior)

I don't have an image of how to use it, which somehow understands the meaning. I decided to write an article for the reason of

What is "hidden_field"?

Used in form_for and form_with Image of sending invisible values

Apparently there is also a "hidden_field_tag" helper These differences will be posted on another day

For the time being, move your hands and try using it, preparation

Create a screen for users to post Before posting, try creating a ** confirmation screen for the content of the post **

User and Post controllers and models Try to create

~/environment/rails/sample_app
❯ rails g controller users 

~/environment/rails/sample_app
❯ rails g model User

~/environment/rails/sample_app
❯ rails g controller posts index new create

~/environment/rails/sample_app
❯ rails g model Post

~/environment/rails/sample_app
❯ rails db:migrate

association

app/model/user.rb


class User < ApplicationRecord
  has_many :posts
end

app/model/post.rb


class User < ApplicationRecord
  has_many :user
end

Enter initial data

While looking at the article I wrote before Enter the initial data of User and Post Article to put the initial data written before

db/seeds.rb


test_user = User.create!(
  name: 'test',
  email: '[email protected]',
  password: 'password'
)

Post.create!(
  title: 'test title',
  contents: 'Post test',
  user_id: test_user.id
)

Post.create!(
  title: 'test title2',
  contents: 'Post test, second time',
  user_id: test_user.id
)

Execute with the following command

rails db:seed

Create a list screen

Description of controller Declaring user acquisition over and over is a hassle Describe with private method

app/controller/posts_controller.rb


class PostsController < ApplicationController
  before_action :set_user

  def index
    @posts = Post.where(user_id: @user.id)
  end

  private

  def set_user
    @user = User.find(1)
  end
end

Create view

rb:app/views/posts/index.html.erb


<h1>Post list screen</h1>

<% @posts.each do |post| %>
  <p><%= post.title %></p>
  <p><%= post.contents %></p>
<% end %>

Routing definition

config/routes.rb


Rails.application.routes.draw do
  get 'posts/index'
end

Create a post creation screen

This is also from the description of the controller

app/controller/posts_controller.rb


class PostsController < ApplicationController
  before_action :set_user

  def index
    @posts = Post.where(user_id: @user.id)
  end

  def new
    @posts = Post.new
  end

  def create
    @posts = Post.create(
      title: params[:post][:title],
      contents: params[:post][:contents],
      user_id: @user.id
    )

    if @posts.save
      redirect_to posts_index_path
    else
      render :new
    end
  end

  private

  def set_user
    @user = User.find(1)
  end
end

Stumble trying to get as "params [: title]" Check parameters Get with ** params [: model name] [: passed name attribute] **

Create view

rb:app/views/posts/new.html.erb


<h1>Post new creation screen</h1>

<%= form_with(model: @posts, url: posts_create_path, local: true) do |f| %>
  <div id="container">
    <%= f.text_field :title %>
    <%= f.text_area :contents %>

    <%= f.submit %>
  </div>
<% end %>

Routing definition

config/routes.rb


Rails.application.routes.draw do
  get 'posts/index'
  #add to
  get 'posts/new'
  post 'posts/create'
end

With this, first of all, ordinary users post I was able to reach the list screen

Finally create a confirmation screen

Add "** confirm action **" for confirm screen to Post controller

app/controller/posts_controller.rb


class PostsController < ApplicationController
  before_action :set_user
  #add to
  before_action :posts_params

  def index
    @posts = Post.where(user_id: @user.id)
  end

  def new
    @posts = Post.new
  end

  #Added action for confirmation screen
  def confirm
    @posts = Post.new(
      title: params[:post][:title],
      contents: params[:post][:contents]
    )
   
    #Returns true if an error occurs, false if there is no error
    if @posts.valid?
      render :confirm
    else
      render :new
    end
  end
  
  #Delete
  def create
    @posts = Post.create(
      title: params[:post][:title],
      contents: params[:post][:contents],
      user_id: @user.id
    )

    if @posts.save
      redirect_to posts_index_path
    else
      render :new
    end
  end

  private

  def set_user
    @user = User.find(1)
  end

  #Strong parameter added
  def posts_params
    params.require(:post).permit(:title, :contents)
  end
end

"Valid?" "Invalid?" Method

There seems to be a difference here as well

valid?」 The result of validation Returns true ** if there are no errors **, false ** if an error occurs

"** invalid? **" is the opposite

From the definition of routing

config/routes.rb


Rails.application.routes.draw do
  get 'posts/index'
  get 'posts/new'
  #Delete
  post 'posts/create'
  #add to
  post 'posts/confirm'
end

view creation

~/environment/rails/sample_app
❯ touch app/views/posts/confirm.html.erb

Modify the view But first I want to test if I go to the confirmation screen

rb:app/views/posts/confirm.html.erb


  <h1>success</h1>

Just fill in When I submitted the form, the URL was It says localhost: 3000/posts/confirm OK if the "Success" screen appears on the screen

We will implement it in more detail

Add an action

app/controller/posts_controller.rb


class PostsController < ApplicationController
  # ~Omitted~

  #Action for confirmation screen
  def confirm
    @posts = Post.new(
      title: params[:post][:title],
      contents: params[:post][:contents]
    )
   
    #Returns true if an error occurs, false if there is no error
    #Described by postfix if
    render :confirm if @posts.valid?
  end

  
  # ~Omitted~
end

Create a view

rb:app/views/posts/confirm.html.erb


<h1>confirmation screen</h1>

<%= form_with(model: @posts, url: posts_complete_path, local: true) do |f| %>
  <div id="container">
    #Appeared here, "hidden_field」
    <%= f.hidden_field :title %>
    <%= @posts.title%>

    <%= f.hidden_field :contents %>
    <%= @posts.contents%>

    #Name attribute that allows you to name the parameter
    <%= f.submit 'Return', name: 'back' %>
    <%= f.submit 'Send' %>
  </div>
<% end %>

A little trouble with the destination of the form -Form_with is sent by "POST" by default -When you create an object using create in the controller, new and save Will go → Therefore, the form is submitted as "PATCH" → "PATCH" is sent when there is already an object

Add an action for the ** completion screen **

app/controller/posts_controller.rb


class PostsController < ApplicationController
  # ~Omitted~

  #Action for confirmation screen
  def confirm
    @posts = Post.new(
      title: params[:post][:title],
      contents: params[:post][:contents]
    )
   
    #Returns true if an error occurs, false if there is no error
    #Described by postfix if
    render :confirm if @posts.valid?
  end

  #Action for completion screen
  def complete
    @posts = Post.new(
      title: params[:post][:title],
      contents: params[:post][:contents],
      user_id: @user.id
    )

    #To parameters[:back]Is attached(back button)Click
    #Or, if the object is not saved, return the "new" screen.
    render :new if params[:back] || [email protected]
  end

  # ~Omitted~
end

With this, you can do the screen transition of ** Post → Confirm → Complete ** Completion of a simple posting application

"Hidden_field" used when pressing the back button

Created view

rb:app/views/posts/confirm.html.erb


<h1>confirmation screen</h1>

<%= form_with(model: @posts, url: posts_complete_path, local: true) do |f| %>
  <div id="container">
    #Appeared here, "hidden_field」
    <%= f.hidden_field :title %>
    <%= @posts.title%>

HTML being created

<input type="text" name="post[title]" id="post_title">

Enter the content and press the back button
<input type="text" value="Test title" name="post[title]" id="post_title">

The entered value is included in" ** value ** " Used when you want to pass a value without letting the user fill in directly from the form

Reference article

https://railsguides.jp/action_view_overview.html https://railsdoc.com/page/hidden_field https://qiita.com/__xxx/items/7c9b194230c7ce2b02ca https://remonote.jp/rails-confirm-form https://web-begginer-log.com/rails-confirm/

Recommended Posts

Find out about Rails hidden_field (create a confirmation screen and check the behavior)
[Rails / ActiveRecord] About the difference between create and create!
A note about the Rails and Vue process
Install Rails in the development environment and create a new application
[Rails] Introduce a simple calendar and insert a "confirmation screen" in additional events
Find out about instance methods and self
[Rails] I learned about the difference between resources and resources
Display a confirmation screen before registering a record with rails
I can't get out of the Rails dbconsole screen
A memorandum about table data types and commands (Rails)
Create a login authentication screen using the session function
[Rails 6.0, Docker] I tried to summarize the Docker environment construction and commands necessary to create a portfolio
Click the [rails] button to create a random alphanumeric password and enter it in the password field
Find out about Docker
[Java] Throw a request and display the screen ② (GET / POST)
Rails6 Couldn't find User with'id' = sign_out and cannot log out
Rails: I've summarized the model and database for a moment.
[Java] Throw a request and display the screen (GET / POST)
[JSP, Servlet] Launch a new project and check the connection !!
A note about the seed function of Ruby on Rails
I want to create a form to select the [Rails] category
About the behavior when doing a file map with java