[RUBY] Delve into Rails form_with

Lightly introduce yourself

Nice to meet you, nice to meet you. My name is Ito. After graduating from university, I became a programmer with no experience, and I realized that I have been working for about 7 or 8 years. I have been a mentor for DMM WebCamp since March 2020.

Target audience

--First touch of MVC framework in Ruby on Rails --I don't see many HTML elements in the validation tool --Beginners

Premise

$ rails -v
Rails 5.2.4.3
$ ruby -v
ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-linux]
$

It's just a Ruby version, Rails 5 series. I haven't considered version compatibility, but I think the content you write doesn't affect that much. ?? I think. It seems that the default behavior is different at ~~ authenticity_token ... It's not the main subject, so please check with each version mm

What I want to tell

** Let's take a look at the verification tool **. It is an article that does not need to be read by those who normally look at attributes such as input name. I only write the basics, so don't be afraid

What is ActionView :: Helpers in the first place? ??

Isn't it the form system that I often use? I think.

Please see the link below for details. https://api.rubyonrails.org/classes/ActionView/Helpers.html

Advance preparation

I will omit the detailed explanation.

Project creation

By the way, the $ mark at the beginning of the line means that it is not the root user #.

python


$ rails new without_action-view-helpers #Project creation
#abridgement
$ cd without_action-view-helpers/
$ rails g controller books index new #controller(Including action)Create
#abridgement
$ rails g model Book title:string price:integer description:text #Modeling
#abridgement
$ rails db:migrate #DB reflection
#abridgement
$

Routing settings

config/routes.rb


Rails.application.routes.draw do
  resources :books, only: [:index, :new, :create, :show, :edit, :update]
end

Check routing


$ rails routes | grep book #grep is searching for strings
                    books GET   /books(.:format)                                                                         books#index
                          POST  /books(.:format)                                                                         books#create
                 new_book GET   /books/new(.:format)                                                                     books#new
                edit_book GET   /books/:id/edit(.:format)                                                                books#edit
                     book GET   /books/:id(.:format)                                                                     books#show
                          PATCH /books/:id(.:format)                                                                     books#update
                          PUT   /books/:id(.:format)                                                                     books#update
$

controller Very simple shape.

app/controllers/books_controller.rb


class BooksController < ApplicationController
  def index
    @books = Book.all
  end

  def new
    @book = Book.new
  end

  def create
    book = Book.new(book_params)
    book.save
    redirect_to books_path
  end

  def show
    @book = Book.find(params[:id])
  end

  def edit
    @book = Book.find(params[:id])
  end

  def update
    book = Book.find(params[:id])
    book.update(book_params)
    redirect_to books_path
  end

  private
  def book_params
    params.require(:book).permit(:title, :price, :description)
  end
end

view

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


<h1>Books#new</h1>

<div>
  <%= render 'books/form', book: @book %>
</div>

It is a partial template.

erb:app/views/books/_form.html.erb


<%= form_with model: book, local: true do |f| %>

  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>

  <div>
    <%= f.label :price %>
    <%= f.number_field :price %>
  </div>

  <div>
    <%= f.label :description %>
    <%= f.text_area :description %>
  </div>

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

<% end %>

Let's dig deeper using the browser's verification tool

new It looks like this with a screenshot スクリーンショット 2020-12-10 20.26.02.png

First form tag and input>Let's start with the hidden part


<form action="/books" accept-charset="UTF-8" method="post">
  <input name="utf8" type="hidden" value="✓">
  <input type="hidden" name="authenticity_token" value="cgX+LsxfzE7A7F5Tm8GAlF2KdaifSdqdrWd6cOgazlcbZx8OQ4c6LazJtdRYIdPjzmfmPUGHkuBoxSQhdSqiIA==">
</form>

action? accept-charset? method? hidden? There are many items that I have not specified.

method method is the http request method when submitted.

action action specifies the URI (path) to be executed when the submit button in the form tag is clicked. Since the method is post in/books, it is a mechanism to jump to the create action of books_controller.

Isn't action specified in form_with?

When the parameter url is not specified, the path of action is created from model without permission. It can be omitted if the model name and controller name match. It's easy because you only have to write model: book.

By the way, if you are using namespace, you can give it as model: [: admin, book] and it will create a URI called / admin/books. Convenient

hidden I haven't looked into name = "utf8"! I will omit it name = "authenticity_token" is automatically issued as a CSRF measure. It is issued so as not to receive unauthorized requests from other sites. This time I tried it with 5.2 series, so it seems that it is enabled by default, but if it is another version, it will be enabled if you set it as needed.

input tag

What are the input items?


<div>
  <label for="book_title">Title</label>
  <input type="text" name="book[title]" id="book_title">
</div>

スクリーンショット 2020-12-13 16.21.27.png

Looking at the input tag It is <input type =" text "name =" book [title] "id =" book_title ">. type =" text " means that you can simply enter text. There are other than text, so you can see this by looking at this. (For more information, see this: http://www.htmq.com/html5/input.shtml) name =" book [title] " I think this is probably the most important thing. In terms of Rails, it means that you can get the value entered by params [: book] [: title] on the controller side. If you understand this, can't the entered value be saved in the DB? I think there will be less such things.

edit

スクリーンショット 2020-12-13 17.08.31.png

Omitted as appropriate


<form action="/books/1" accept-charset="UTF-8" method="post">
  <input type="hidden" name="_method" value="patch">
  <div>
    <label for="book_title">Title</label>
    <input type="text" value="Taitoru" name="book[title]" id="book_title">
  </div>

  <div>
    <input type="submit" name="commit" value="submit" data-disable-with="submit">
  </div>

</form>

form tag, hidden tag

The action part is action ="/books/1 ". If the variable book specified in model: book is saved, the URI is automatically set to book.id.

There is a hidden tag that wasn't there when it was new. <input type =" hidden "name =" _ method "value =" patch "> Now the http method is patch. Why not specify it in the form tag? ?? I think that is probably because form> method can only specify post/get (if you make a mistake, please point out: bow :). http://www.htmq.com/html5/form.shtml

input tag

<input type =" text "value =" Taitoru "name =" book [title] "id =" book_title ">

The number of items called value = "Taitoru" is increasing. This specifies the value of the input part. Other than that, it is the same, so I will omit it.

Summary

By checking and being aware of how HTML is generated, rather than simply looking at what is displayed on the screen, it has become possible to gradually understand the mechanism of HTML and Rails. I think I will go.

I'm not very good at writing long sentences, but I hope it helps. .. .. Thank you to the mentors who spoke to us again.

Recommended Posts

Delve into Rails form_with
[Rails] form_with
[Rails] Completely understand form_with
Incorporate circleCI into CircleCI Rails app
[Rails] Two ways to write form_with
Incorporate Elasticsearch into your Rails app
Rails form_with communicates Ajax by default
[Rails] About helper method form_with [Basic]
[Introduction to Rails] form_with (local: true)
[Form with two arguments] rails, form_for / form_with arguments
[Rails] About local: true described in form_with
[Rails] How to translate devise into Japanese