[Rails] Save information from one form to multiple tables

Introduction

Send three pieces of information, "user information", "book", and "genre" from one form, Implement the function to save in separate table using ** Form object **.

Specifically, the class defined by myself is provided with the function corresponding to the form_with method and the function to perform validation, and the instance method of the class is used to save to multiple tables.

Form object

A Form object is one of Rails' design patterns.

This design pattern is "when you want to operate multiple models with one form submission", It is used when you want to validate the information that is not saved in the table. It means that the same process can be used in many models by cutting out the one in which various processes such as validation are originally written in the form layer.


Implementation

Model file to be cut out in the form layer Set to include "ActiveModel :: Model" and "attr_accessor"

user_book.rb


class UserBook
  include ActiveModel::Model
  attr_accessor :nickname, :age, :gender, :book_title, :genre

end

○ActiveModel::Model When you include ActiveModel :: Model in a class, the instance of that class can be treated as an argument of helper methods such as form_with and render like the instance of the class that inherits ActiveRecord, and the validation function can be used. A class that includes ActiveModel :: Model to implement the Form object pattern is sometimes called a "Form object".

○attr_accessor It is a method that defines getters and setters in the written class. It sets attributes based on the given arguments and defines a method (getter) to get them and a method (setter) to update them.

-Definition of method that can get value (getter) -Definition of a method that can update the value (setter)

By defining getters and setters for all attributes used in this form (that is, all column names of each table you want to save), you can use them as arguments of form_with when you create an instance of this Form object. I will.

○ Describe the process to cut out

user_book.rb


class UserBook
  include ActiveModel::Model
  attr_accessor :nickname, :age, :gender, :book_title, :genre

  with_options presence: true do
    validates :nickname
    validates :age
    validates :genre
  end

  def save
    user = User.create(nickname: nickname, age: age, gender: gender)
    Book.create(book_title: book_title, user_id: user.id)
    Genre.create(genre: genre, user_id: user.id)
  end
end

With all the validations you want to set In def save ~ end I am writing a process to save the information sent as a parameter from the form in a table.

○ Create an instance of Form object

Define book_params to format all the information sent from the form into hash format, It is used to call this in the create action to create an instance of the UserBook class.

books_controller.rb


class BooksController < ApplicationController
  def index
  end

  def new
    @user_book = UserBook.new
  end

  def create
    @user_book = UserBook.new(book_params)
      if @user_book.valid?
        @user_book.save
        redirect_to action: :index
      else
        render action: :new
      end
  end

  private
  
  def book_params
    params.require(:user_book).permit(:nickname, :age, :gender, :book_title, :genre)
  end
end

○ Pass an instance of Form object as an argument

Pass the created Form object instance as an argument to the form_with method of new.html.erb so that the input information will be processed through MVC.

ruby:app/views/books/new.html.erb


<%= form_with(model: @user_book, url: donations_path, local: true) do |form| %>
  <%= render 'error_messages', model: @user_book %>

  #Form contents

<% end %>

This article is based on the following. https://product-development.io/posts/rails-design-pattern-form-objects

Recommended Posts

[Rails] Save information from one form to multiple tables
How to save to multiple tables with one input
Establish a search bar in Rails ~ Join multiple tables to search
[Rails] Keyword search in multiple tables
[rails] How to display db information
Add & save from rails database creation
How to implement a slideshow using slick in Rails (one by one & multiple by one)
From pulling docker-image of rails to launching
[Rails] How to convert from erb to haml
[Rails] Assigning variables from controller to JavaScript
From (form)
[Rails] Yeah! Active Strage! Competent Gem! ~ You can save images from two tables ~
[Java] From two Lists to one array list
Rails Tutorial Chapter 1 From Zero to Deployment [Try]
[Java] Get multiple values from one return value
One way to redirect_to with parameters in rails
[Rails] How to upload multiple images using Carrierwave
I want to play with Firestore from Rails
Convert error messages to Japanese Supports multiple tables
[Rails] Introducing pay.jp (from view customization to registration)