Rails: リソースの一括登録画面: 1: 一括登録機能の実装

外観

目的

上記の Set up your coworker's account 画面に触発されて、リソースの一括登録画面を作ってみようと思いました。この画面は招待メールを送信する機能を提供しますが、習作アプリではアカウントの一括登録だけを扱おうと考えています。

最終的に上記のような画面を作ってみる予定です。今のところ、一括登録機能、妥当性確認、子フォームの動的追加/削除機能を段階的に実装してみようと考えています。

環境

ruby 3.1.
Rails 7.0.2.3

一括登録機能の実装

実装

初回は次のようなAccountを2件まとめて登録する画面を作ろうと思います。

名前とメールアドレスを持つAccountモデルを作成します。
Accountを登録する画面とコントローラーの足場を作成します。
モデルにメールアドレスを用意しましたが、一括登録機能の実現に注力したいため、画面を簡素化して名前のみを使用したいと思います。

rails new bulk_account
cd bulk_account
bin/rails g model Account name email
bin/rails db:migrate
bin/rails g controller BulkAccounts new

config/routes.rb
新規登録画面とリソース作成のルーティングを用意します。

Rails.application.routes.draw do
  resources :bulk_accounts, only: %i[ new create ]
  root to: redirect("/bulk_accounts/new")
end

app/models/account.rb
Accountの名前を必須入力にします。

class Account < ApplicationRecord
  validates :name, presence: true
end

app/controllers/bulk_accounts_controller.rb

new
Accountを2件作成して新規登録画面に渡します。

create
accounts_params は、画面から引数で渡された Account の配列を返します。
上記から Account 配列を作成し valid? で各々の妥当性を確認します。
作成した Account 配列を @accounts に設定します。
一つでもエラーがあった場合は、@accounts を新規登録画面に渡して該当する項目にエラーメッセージを表示します。
エラーがない場合は、Account 配列を保存して、新規登録画面にリダイレクトします。

class BulkAccountsController < ApplicationController
  def new
    @accounts = 2.times.map{ Account.new }
  end

  def create
    @accounts = accounts_params.map { Account.new(_1).tap(&:valid?) }
    if @accounts.none? { _1.errors.any? }
      @accounts.each(&:save)
      redirect_to new_bulk_account_url
    else
      render :new, status: :unprocessable_entity
    end
  end

  private
    def accounts_params
      params.require(:accounts).map { _1.permit(:name) }
    end
end

app/views/bulk_accounts/new.html.erb
Account 一括登録用のフォームを表示します。
@accounts の数だけ入力項目を表示します。
一度登録してエラーがあった場合、該当項目にエラーメッセージを表示します。

<h1>New accounts</h1>

<%= form_with(url: :bulk_accounts) do |form| %>
  <% @accounts.each do |account| %>
    <%= fields_for "accounts[]", account do |account_fields| %>
      <div>
        <%= account_fields.label :name, style: "display: block" %>
        <%= account_fields.text_field :name %>
        <% if account.errors[:name].any? %>
          <div style="color: red">
            <%= account.errors.full_messages_for(:name).first %>
          </div>
        <% end%>
      </div>
      <hr>
    <% end %>
  <% end %>
  <div>
    <%= form.submit %>
  </div>
<% end %>

課題

Account のメールアドレスの妥当性確認を行なっていません。
Account の登録数を増減できません。

以上です。

続きを書きました。

この記事が気に入ったらサポートをしてみませんか?