Ruby on Rails6 Practical Guide [Extensions] cp7 ~ cp9 [Memo]

Introduction

The author of this article is a beginner just starting to learn programming. I would appreciate it if you could point out any mistakes.

Overview

This article is a personal memo of what I learned by reading the Ruby on Rails 6 Practical Guide. It seems to be difficult to read because it is excerpted and picked up. Excuse me. This book also has a sequel Extension, and both books have been studied at the stage of writing the article. I will write an article for review as well. I will skip cp1 and cp2 of the function extension because they explain the environment construction and the code of the main part.

Previous article Ruby on Rails6 Practical Guide cp4 ~ cp6 [Memo] Ruby on Rails6 Practical Guide cp7 ~ cp9 [Memo] Ruby on Rails6 Practical Guide cp10 ~ cp12 [Memo] Ruby on Rails6 Practical Guide cp13 ~ cp15 [Memo] Ruby on Rails6 Practical Guide cp16 ~ cp18 [Memo] Ruby on Rails6 Practical Guide [Extensions] cp3 ~ cp6 [Memo]

Function Expansion Chapter 7 Complex Form

Specify the method in before_validation

before_validation :set_application_start_time

private def set_application_start_time
#Logic omitted
end

before_validation executes the corresponding method when a symbol is given as an argument.

There was a lot of interesting code, but I'll omit this chapter because it was difficult to cut out general-purpose information. I would like to read it again.

Extensions Chapter 8 Transactions and Exclusive Locks

It is called race condition </ strong> that the result of multiple processes running in parallel brings unexpected results depending on the order and timing. Race conditions in database processing can be resolved by making good use of exclusive locks </ strong>.

The code below is processing to apply for the program.

def accept(program)
  ActiveRecord::Base.transaction do
    program.lock!
    if max = program.max_number_of_paticipants
      if program.entries.where(canceled: false).count < max
        program.entries.create!(customer: @customer)
        return :accepted
      else
        return :full
      end
    else
      program.entries.create!(customer: @customer)
      return :accepted
    end
  end
end
  • This is the code that moves the controller processing to the instance method of the service object class.
  • Return returns the symbol to the controller. On the controller side, processing is branched according to the return value.

In the code above, the process is branched depending on whether the maximum number of participants is defined or the maximum number of participants is reached. If applications are made at the same time with the maximum number of participants, there is a risk that the number of participants will be exceeded. Use lock! To get an exclusive lock on the object's table record. A transaction must be started to acquire an exclusive lock. If an exception occurs in a transaction block, all processing rolls back. You must use save! Or create! To raise an exception if saving to the database fails.

Function expansion Chapter 9 Form confirmation screen

Implementation of confirmation screen

If you click the update button on the confirmation screen, it will be saved in the database, and if you click the correction button, you will return to the input form.

confirm action

# PATCH
def confirm
  @confirm_form = Customer::AccountForm.new(current_customer)
  @customer_form.assign_attributes(params[:form])
  if @customer_form.valid?
     render action: "confirm"
  else
    flash.now.alert = "There is an error in the input."
    render action: "edit"
  end
end
  • Customer :: AccountForm is a form object class. Only validation is done without saving to the database.

view template for confirm action

haml:_confirm.html.haml


= form_with model: @customer_form, scope: "form",
    url: :customer_account do |f|
  = f.label :family_name
  .field-value.readonly
    = @customer_form.customer.send(family_name)
  = f.hidden_field :family_name
  = f.submit "update"
  = f.submit "correction", name: "correct"
    

The information sent to the server is hidden in hidden_field.

update action

def update
  @confirm_form = Customer::AccountForm.new(current_customer)
  @customer_form.assign_attributes(params[:form])
  if params[:commit]
    if @customer_form.save
       flash.notice = "Updated account information."
       redirect_to :customer_account
    else
      flash.now.alert = "There is an error in the input."
      render action: "edit"
    end
  else
    render action: "edit"
  end
end

Whether the correction button or the update button is pressed is determined by whether the value commit is set in the parameter.

  = f.submit "update"
  = f.submit "correction", name: "correct"

You can give the name option to the submit method. The default is commit. When the update button is pressed, the parameter of the key "commit" is extended, and when the correct button is pressed, the parameter of the key "correct" is extended to the update action.

Continued

We will add the URLs of the following articles one by one.

Ruby on Rails6 Practical Guide [Extensions] cp10 ~ cp12 [Memo]

Quote source

Recommended Posts