Before registering, a confirmation screen will appear, and after confirming there, set the data to be registered. First, write the action (conform_new action) that displays the confirmation screen on the controller.
app/controller/tasks_controller.rb
def confirm_new
@task = current_user.tasks.new(task_params)
render :new unless @task.valid? #If in the database@Execute if there is no task
Then fill in the routing
config/routes.rb
resources :tasks do
post :confirm, action: :confirm_new, on: :new
end
post :confirm, action: :confirm_new, on: :new This part originally had the following shape
config/routes.rb
resources :tasks do
new do
post :confirm, action: :confirm_new
end
end
If there is only one element in the new block, it will be routed by using on :: block name after it.
Next, create a confirmation screen view
slim:app/views/tasks/confirm_new.html.slim
h1 Confirmation of new contents
= form_with model: @task, local: true do |f|
table.table.table-hover
tbody
tr
th= Task.human_attribute_name(:name)
td= @task.name
=f.hidden_field :description
tr
th= Task.human_attribute_name(:description)
td= simple_format(@task.description)
=f.hidden_field :description
=f.submit 'Return', name: 'back', class: 'btn btn-secondary mr-3'
=f.submit 'Registration', class: 'btn btn-primary'
There are two buttons on the confirmation screen above, a back button and a registration button. If you want the back button to work, you need to determine which of these two buttons is pressed. Therefore, back is added to the name attribute of the back button. In programming, if back of the name attribute is pressed, it will return to the original operation. In other words, the result of params [: back] should be obtained. You can write the action of returning to the original when params [: back] is pressed in the create action.
app/controllers/tasks_controller.rb
def create
@task = current_user.tasks.new(task_params)
if params[:back].present? #present?Is a boolean value that is true if there is a value
render :new
return
end
Types of methods used for boolean values
Method name | Method meaning |
---|---|
nil? | True if the value of the variable is nil or no value |
empty? | The value of the variable is""True if (for strings) or if the value is blank. nil?The difference with is empty?May have a variable value, but that value indicates empty |
blank? | True if there is no value |
present? | True if there is a value |
As the number of tasks in the task list increases, it becomes difficult to find them one by one. It would be convenient to have a search function at such times. Use a gem called Ransack to add a search function
7-2-2 Search by name Add search functionality with Ransack
app/controllers/tasks_controller.rb
def index
@q = current_user.task.ransack(params[:q])
@task = @q.result(distinct: true).recent
end
@q = current_user.task.ransack(params[:q])
In ransack, search by taking query parameter (params [: q]) Search the task of the logged-in user with ransack and put it as @q
@task = @q.result(distinct: true).recent
@Q that came out in the search Excluding duplicate search results (result (distinct: true)) Display in order of registration date and time (recent)
Now that we have implemented ransack, let's actually search in the view. Use search_form_for to add search functionality
slim:app/views/tasks/index.html.slim
h1 task list
= search_form_for @q, class: 'mr-5' do |f|
.form_group.row
=f.label :name_cont, 'name', class: 'col-sm-2 col-form-label'
.col-sm-10
=f.search_field :name_cont, class: 'form-control'
.form-group.row
=f.label :created_at_gteq, 'Registered Date', class: 'col-sm-2 col-form-label'
.col-sm-10
= f.search_field :created_at_gteq, class: 'form-control'
.form-group
=f.submit class: 'btn btn-outline-primary'
= link_to 'sign up', new_task_path, class: 'btn btn-primary mb-3'
name_cont: Select the one that partially matches name. .search_field: Where to fill in created_at_gteq: Select a post that is larger than the posted date and time (future: gteq)
app/controllers/tasks_controller.rb
def index
@q = current_user.task.ransack(params[:q])
@task = @q.result(distinct: true).recent
end
I used to sort by recent, but next I will sort in any order First take resent
app/controllers/tasks_controller.rb
def index
@q = current_user.task.ransack(params[:q])
@task = @q.result(distinct: true)
end
ruby:app/views/tasks/index.html.slim
table.table.table-hover
thead.thead-default
tr
th= sort_link(@q, :name, default_order: :desc)
th= Task.human_attribute_name(:created_at)
th
If you add sort_link, you will be able to perform sort operations. The first argument is the value obtained by ransack (here @q) The second argument is the column to be sorted (name in this case) default_order: :desc
Rails uses a mechanism called mailer to send emails. Compose and send emails using mailers. Mailer describes in mailer file
app/mailers/task_mailer.rd
class TaskMailer < ApplicationMailer
def creation_email(task)
@task = task
mail(
subject: 'Task creation completion email'
to: 'user@example'
from: 'taskleaf@example'
)
end
end
Set mail of information such as subject, to, from as creation_email method
Make it possible to actually send emails
app/controllers/tasks_controller.rb
def create
@task = current_user.tasks.new(task_params)
if params[:back].present?
render :new
return
end
if @task.save
TaskMailer.creation_email(@task).deliver_now
redirect_to @task, notice: "task"#{@task.name}Was registered"
else
render :new
end
end
If you add TaskMailer.creation_email (@task) .deliver_now as above, an email about @task will be sent. deliver_now is a method for immediate transmission. There is also a deliver_later method
A file management gem called Active Storage comes out and uses them to attach photos and images. To actually attach it, attach it by the following method
app/models/task.rb
class Task < ApplicationRecord
has_one_attached :image
....
end
By using the has_one_attached method, it is possible to associate one image with one task.
ruby:app/views/tasks/_form.html.slim
...
...
...
.form-group
=f.label :image
=f.file_field :image, class: 'form-control'
...
end
Also set "image: image" in ja.yml Allow both permit and image of task_params method
Write the code so that it also appears on the confirmation screen
ruby:app/views/tasks/show.html.slim
...
tr
th= Task.human_attribute_name(:image)
td= image_tag @task.image if @task.image.attached?
tr
...
...
...
if @ task.image.attached? Indicates whether the image is attached. If there is an actual image, display it with image_tag
The more tasks there are, the heavier the method of displaying all the information that has been done so far. Pagination is a method of distributing information depending on the page and lightening the operation by passing the display to the next page when the number of files exceeds a certain number. A gem file called kaminari is used for this pagination.
Original tasks_controller file
app/controllers/tasks_controller.rb
def index
@q = current_user.task.ransack(params[:q])
@task = @q.result(distinct: true)
end
By adding .page (params [: page]) to the end, you can determine the number of items to be displayed per page (25 items per page by default).
app/controllers/tasks_controller.rb
def index
@q = current_user.task.ransack(params[:q])
@task = @q.result(distinct: true).page(params[:page])
end
Next, make it actually reflected in the view file
ruby:app/views/tasks/index.html.slim
.mb-3
=paginate @tasks
=page_entries_info @tasks
...
...
...
It is created automatically by using the paginate helper method and the page_entries_info helper method.
Rails provides a framework called Active Job to perform various processes asynchronously in the background. ActiveJob is used when:
・ The processing is heavy and keeps the user waiting. ・ I want you to take action at the specified date and time
The mechanism called sidekiq is used in such a case.
① First, synchronize Rails and sideskiq
config/environments/development.rb
config.active_job.queue_adapter = :sideskiq
② Create app / jobs / sample_job.rb and create perform method
app/jobs/sample_job.rb
class SampleJob < ApplicationJob
queue_as :deault
def perform(*args)
Sidekiq::Logging.logger.info "I ran a sample job"
end
end
Call the perform method to process
app/controller/tasks_controller.rb
def create
@task = current_user.tasks.new(task_params)
...
if @task.save
TaskMailer.created_email(@task).deliver_now
SampleJob.perform_later
...
...
...
SampleJob.perform_later now performs asynchronous processing
If you use the set method, you can execute the process by specifying the date and time.
#Run at noon the next day
SampleJob.set(wait_until: Date.tomorrow.noon).perform_later
#Run after a week
SampleJob.set(wait: 1.week).perform_later
Recommended Posts