In this article, I will explain the partial, which is a function for using a common file on multiple pages.
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
Task edit page
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'
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.
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 ...
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