【Rails 6.0】 복수 레코드의 일괄 보존에 대해서

11987 단어 Rails6루비Rails

소개



개인 앱에서 수주 관리 기능을 구현했기 때문에 그 때 배운 여러 레코드를 일괄 저장하는 방법에 대해 출력합니다.

참고 자료



이번 기사를 작성함에 있어서, 이하의 기사를 많이 참고로 했습니다. 정말 고마워요.
【Rails 5】모델을 일괄 등록하는 순서
【Rails 6】form_with를 이용하여 일괄 등록하기
1.2. 일괄 등록 양식 구현

제작물




チェックボックスにチェックを入れた商品のみを登録する



전제 조건



Product 모델


Column
유형


이름
문자열

price
integer

unit
문자열

availability
부울



models/product.rb
class Product < ApplicationRecord

  with_options presence: true do
   validates :name
   validates :unit
   validates :price, numericality: {only_integer: true, greater_than_or_equal_to: 0 }
   validates :availability, inclusion: { in: [true, false] }
  end

end


정책


  • 여러 상품을 일괄 저장하기위한 컬렉션 모델 만들기
  • 컨트롤러에서 일괄 등록을위한 처리 설명
  • 보기 화면에서 여러 제품을 일괄 등록 할 수있는 양식을 만듭니다.

    1. 복수 상품을 일괄 저장하기 위한 컬렉션 모델을 작성



    models 디렉토리에 form 디렉토리를 작성하고, 그 안에 ProductCollection 모델과 Base 모델을 작성합니다.

    models/form/product_collection
    class Form::ProductCollection < Form::Base
      FORM_COUNT = 10 #ここで、作成したい登録フォームの数を指定
      attr_accessor :products 
    
      def initialize(attributes = {})
        super attributes
        self.products = FORM_COUNT.times.map { Product.new() } unless self.products.present?
      end
    
      def products_attributes=(attributes)
        self.products = attributes.map { |_, v| Product.new(v) }
      end
    
      def save
        Product.transaction do
          self.products.map do |product|
            if product.availability # ここでチェックボックスにチェックを入れている商品のみが保存される
              product.save
            end
          end
        end
          return true
        rescue => e
          return false
      end
    end
    
    

    models/form/base.rb
    class Form::Base
      include ActiveModel::Model
      include ActiveModel::Callbacks
      include ActiveModel::Validations
      include ActiveModel::Validations::Callbacks
    
    end
    

    2. 컨트롤러에서 인스턴스 생성 및 데이터 처리



    controllers/products_controller.rb
    
    class ProductsController < ApplicationController
    
      def new
        @form = Form::ProductCollection.new
      end
    
      def create
        @form = Form::ProductCollection.new(product_collection_params)
        if @form.save
          redirect_to products_path, notice: "商品を登録しました"
        else
          flash.now[:alert] = "商品登録に失敗しました"
          render :new
        end
    
      end
    
      private
    
        def product_collection_params
            params.require(:form_product_collection)
            .permit(products_attributes: [:name, :price, :unit, :availability])
        end
    
    end
    
    
    @form = Form::ProductCollection.new 는 방금 만든 모델의 인스턴스를 생성합니다.
    스트롱 매개변수는 products_attributes에서 수신됩니다.

    3. 뷰 화면에서 복수의 상품을 일괄 등록할 수 있는 폼을 작성



    views/products/new.html.haml
    = form_with model: @form, url: products_path, method: :post, local: true do |form|
      %table
        %thread
          %tr
            %th 登録
            %th 商品名
            %th 販売価格(円)
            %th 発注単位
      %tbody
        = form.fields_for :products do |f|
          %tr
            %td.text-center
              = f.check_box :availability
            %td
              = f.text_field :name
            %td
              = f.text_field :price
            %td
              = f.text_field :unit
      = form.submit "一括登録"
      = link_to "戻る", :back
    

    form_with와 fields_for를 사용하여 여러 등록할 수 있는 양식을 작성하고 있습니다.

    이제 일괄 저장이 가능하다고 생각합니다.

    마지막으로



    봐 주셔서 감사합니다. 뭔가 실수가 있으면 지적을 부탁드립니다.
  • 좋은 웹페이지 즐겨찾기