Commentary on partial! --Ruby on Rails

Introduction

In this article, I will explain the partial, which is a function for using a common file on multiple pages.

What is a partial?

It's a partial that you often see in Ruby on Rails, but what exactly is it?

In the early stages of Rails learning, it is often explained as __ "How to share files with the same layout on multiple pages" __.

For example, suppose you have a simple task management app with a new task registration page and a task edit page inside.

New task registration page e4b93bb581673f73b2a795aaa5233fe6.png

Task edit page 45a46fc86db90f64820687aba42a9e7a.png

As you can see at a glance, the layout is almost the same. I've used a layout that's too simple to give a clear example, but it's likely that multiple pages will have similar layouts due to the unified layout of the site.

In fact, the structure of the files on these two pages also has a lot in common, which seems wasteful. (It's against Ruby's __DRY (Don't Repeat Yourself) __, isn't it?). Below form_with is exactly the same, isn't it? In addition, this time, slim was used instead of erb in the reference text, so I am using it as it is mm

_ New task registration page file _

slim:app/views/tasks/new.html.slim


New registration of h1 task

.nav.justify-content-end
  / tasks_path = /tasks
  = link_to 'List', tasks_path, class: 'nav-link'

= form_with model: @task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_name'
  = f.submit nil, class: 'btn btn-primary'

_ Task edit page file _

slim:app/views/tasks/edit.html.slim


h1 task editing

.nav.justify-content-end
  = link_to  "List", tasks_path, class: 'nav-link'

= form_with model: @task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_name'
  = f.submit nil, class: 'btn btn-primary'

Common using partials

We will standardize using the partial, which is the main subject.

The first thing to do is create a file called app/views/tasks/_form.html.slim as a partial template. Then paste the intersection of the file on the new task registration page and the file on the task edit page. (Delete the intersection from the two files!) Also, change the instance variable @ task to task. (I'll explain why later!)

slim:app/views/tasks/_form.html.slim


= form_with model: task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_name'
  = f.submit nil, class: 'btn btn-primary'

As a general rule, it is common to add _ (underscore) to the beginning of the template file name, such as _form.html.slim.

Then put the same code render partial:" form ", locals: {task: @task} in the clean new task registration page file and the task edit page file.

slim:app/views/tasks/new.html.slim


New registration of h1 task

.nav.justify-content-end
  = link_to 'List', tasks_path, class: 'nav-link'

= render partial: "form", locals: { task: @task }

slim:app/views/tasks/edit.html.slim


h1 task editing

.nav.justify-content-end
  = link_to  "List", tasks_path, class: 'nav-link'

= render partial: "form", locals: { task: @task } 

The optional parts partial and locals of render partial:" form ", locals: {task: @task} are generally omitted, but for the sake of explanation, they are not omitted. If omitted, it will be written as render" form ", {task: @task}.

First, specify the template file to load with partial:. Since the template file is in the same folder this time, it can be read with " form ", but if there is a partial file in another folder, it is necessary to specify the file to be read including the folder.

locals: is confusing at first glance, but roughly speaking, it means __ to put the contents of __ instance @ task in the local variable task and pass it to the partial template file. That is, the value of the instance variable is passed to the variable task in the task: @task part.

task = @task

And it is an image of passing task to a partial as a local variable bylocals:.

This will enable the local variable task in the partial, and the task described earlier in the partial will also be valid.

This is the end of standardization. The layout hasn't changed, and the contents of the file have been cleaned up by making it common.

Reasons to use local variables for partials

Contrary to this implementation method, you can implement it with instance variables without any problem.

slim:app/views/tasks/_form.html.slim


/Instance variables@remain task
= form_with model: @task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_name'
  = f.submit nil, class: 'btn btn-primary'

slim:app/views/tasks/new.html.slim


New registration of h1 task

.nav.justify-content-end
  = link_to 'List', tasks_path, class: 'nav-link'

/Instance variables are passed partially by not specifying local variables
= render partial: "form"

So why bother to change it to a local variable?

In fact, if you use instance variables partially, you will have the problem of __reusability.

If you use an instance variable created by the controller for the partial, the relationship between the __ controller and the partial will be tightly coupled __. In other words, changes on the controller side directly affect the partial. This reduces the reproducibility of partials called from multiple views.

For example, if you rename a controller instance variable, you must change the partial instance variable as well. In addition, controllers in other views using that partial must be renamed to the same instance variable. Reusability is collapsing ...

At the end

What did you think.

I think partials are very often used.

A layout that is too simple like this example is easy, but a page that is so simple would not be so. However, when considering the uniformity of the UI, partials are often used. It's clear to use partials for parts that are common to all pages, such as headers and footers.

Please try to master the partial!

Recommended Posts

Commentary on partial! --Ruby on Rails
Ruby on Rails Elementary
Ruby on Rails basics
Ruby On Rails Association
Ruby on rails learning record -2020.10.03
Portfolio creation Ruby on Rails
Ruby on rails learning record -2020.10.04
[Ruby on Rails] Debug (binding.pry)
Ruby on rails learning record -2020.10.05
Ruby on rails learning record -2020.10.09
Ruby on Rails config configuration
Ruby on Rails basic learning ①
Ruby on rails learning record-2020.10.07 ②
Ruby on rails learning record-2020.10.07 ①
Cancel Ruby on Rails migration
Ruby on rails learning record -2020.10.06
Ruby on Rails validation summary
Ruby on Rails Basic Memorandum
Ruby on Rails Overview (Beginner Summary)
[Ruby on Rails] Read try (: [],: key)
[Ruby on Rails] yarn install --check-files
Ruby on Rails variable, constant summary
Installing Ruby + Rails on Ubuntu 18.04 (rbenv)
[Ruby on Rails] Introduced paging function
Basic knowledge of Ruby on Rails
Progate Ruby on Rails5 Looking Back
How to use Ruby on Rails
[Ruby on Rails] Add / Remove Columns
Ruby on Rails Japanese-English support i18n
(Ruby on Rails6) "Erase" posted content
[Ruby on Rails] CSV output function
Ruby on Rails 6.0 environment construction memo
[Ruby on Rails] What is Bcrypt?
[Ruby on Rails] Confirmation page creation
Ruby On Rails devise routing conflict
[Ruby on Rails] Comment function implementation
[Ruby on Rails] DM, chat function
[Ruby on Rails] Convenient helper method
[Ruby on Rails] Stop "looping until ..."
[Ruby on Rails] Introduction of initial data
[Ruby on Rails] Search function (not selected)
[Rails] Addition of Ruby On Rails comment function
[Ruby on Rails] Creating an inquiry form
Ruby on Rails6 Practical Guide cp13 ~ cp15 [Memo]
[Ruby on Rails] View test with RSpec
[Ruby on Rails] How to use CarrierWave
[Ruby on Rails] 1 model CRUD (Routing Main)
Ruby on Rails installation method [Mac edition]
[Ruby on Rails] model, controller terminal command
Let's summarize "MVC" of Ruby on Rails
Ruby on Rails model creation / deletion command
[Ruby on Rails] About bundler (for beginners)
part of the syntax of ruby ​​on rails
Tailwind on Rails
Ruby on Rails6 Practical Guide cp7 ~ cp9 [Memo]
Ruby on Rails in Visual Studio Codespaces
[Ruby on Rails] Follow function implementation: Bidirectional
Notes on using FCM with Ruby on Rails
[Ruby on Rails] Controller test with RSpec
Deploy to Heroku [Ruby on Rails] Beginner
[Ruby on Rails] Image slideshow using Skippr