[RUBY] Rails learning day 3 part 2

Ruby on Rails5 Quick Learning Practice Guide chapter7

7-1 Insert a confirmation screen before registering or editing

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'

7-1-3 Corresponds to the transition from the "Back" button in the registration action.

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

7-2 Add a search function to the list screen

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)

7-3 Add a sort function to the list screen

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

7-4 Send an email

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

7-4-3 Email transmission process

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

7-5 Upload the file and attach it to the model

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

7-7 Pagination

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.

7-8 Perform asynchronous processing and periodic execution (Job scheduling)

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

7-8-3 Specify execution date and time

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

Rails learning day 3 part 2
Rails learning Day 1 Part 2
Rails learning day 4
Rails learning day 2
rails learning day 1
Programming learning day 3
Rails Docker ~ Part 1 ~
Rails Docker ~ Part 2 ~
java learning day 2
java learning day 1
Rails Tutorial Chapter 3 Learning
[Rails] Learning with Rails tutorial
Rails Tutorial Chapter 4 Learning
Rails Tutorial Chapter 1 Learning
Rails Tutorial Chapter 2 Learning
Ruby on rails learning record -2020.10.04
Ruby on rails learning record -2020.10.05
4th day of java learning
Ruby on Rails basic learning ①
Ruby on rails learning record-2020.10.07 ②
Ruby on rails learning record-2020.10.07 ①
Ruby on rails learning record -2020.10.06
Rails 5 Code Reading Part 2 ~ Action View ~
rails learning rake task, cron, whenever
Rails Tutorial 6th Edition Learning Summary Chapter 10
Rails Tutorial 6th Edition Learning Summary Chapter 7
Rails Tutorial 6th Edition Learning Summary Chapter 4
Rails Tutorial 6th Edition Learning Summary Chapter 9
Rails Tutorial 6th Edition Learning Summary Chapter 6
part of the syntax of ruby ​​on rails
Rails Tutorial 6th Edition Learning Summary Chapter 5
Rails Tutorial 6th Edition Learning Summary Chapter 2
Rails Tutorial Chapter 0: Preliminary Basic Knowledge Learning 5
Rails Tutorial 6th Edition Learning Summary Chapter 3
Muscle Ruby on Rails Day 1 ~ Environment Construction ~
Rails Tutorial 6th Edition Learning Summary Chapter 8