はじめに
railsを利用してポートフォリオを制作しました。制作するにあたって、会員登録時に別モデル内にレコードを作成したいと思いました。
その機能を実装したいと思った理由は、ゲームの成績を管理するスコアシートを制作したかったからです。
会員登録と同時にプレイヤー名としても勝手に登録してくれることで、スコアシートを作成する際に参加しているプレイヤーとして自身の名前が選べるようにする為です。
実装するにあたりfields_forを使用しました。伝わりづらいかもしれませんが自分なりにまとめてみようと思います。
やり方
会員登録に関してはdeviseを使用しました。
こちらが新規登録を行うページです。
<h2>新規登録画面</h2>
<%= form_with model: @user, url: user_registration_path do |f| %>
<p>
<%= f.label :name, "会員名" %>
<%= f.text_field :name, autofocus: true, autocomplete: "name" %>
</p>
<p>
<%= f.label :email, "メールアドレス" %>
<%= f.email_field :email, autocomplete: "email" %>
</p>
<p>
<%= f.label :password, "パスワード" %>
<%= f.password_field :password, autocomplete: "new-password" %>
</p>
<%= f.submit "登録" %>
<% end %>
このページにfields_forを記述することで新規登録時に別レコードを作成出来るようになります。
必要なこと
モデルへの記述が必要です。
fields_forを利用することで異なるモデルを編集できるようになります。
そのためにモデル同士のアソシエーションを指定しなければなりません。
今回は会員を登録するUserモデルとゲームに参加するプレイヤーを登録するPlayerモデルがあります。
一人の会員がゲームに参加するプレイヤーを多数登録出来る仕様です。
なのでUserモデルとPlayerモデルは1対多になります。
class User < ApplicationRecord
has_many :players, dependent: :destroy
end
class Player < ApplicationRecord
belongs_to :user
end
次にhtml.erbにfields_forを記述します。
今回はパスワード入力フォームと登録ボタンの間に記述しました。
<h2>新規登録画面</h2>
<%= form_with model: @user, url: user_registration_path do |f| %>
<p>
<%= f.label :name, "会員名" %>
<%= f.text_field :name, autofocus: true, autocomplete: "name" %>
</p>
<p>
<%= f.label :email, "メールアドレス" %>
<%= f.email_field :email, autocomplete: "email" %>
</p>
<p>
<%= f.label :password, "パスワード" %>
<%= f.password_field :password, autocomplete: "new-password" %>
</p>
<%= f.fields_for :players, Player.new do |s| %>
<%= s.hidden_field :name, :value => "自分" %>
<%= s.hidden_field :myself_status, :value => true %>
<% end %>
<%= f.submit "登録" %>
<% end %>
nameカラムに"自分"、myself_statusに"true"の値が入ります。
hidden_fieldで記述しているため、実際のページには表示されませんが検証モードで存在していることを確認できます。
以上で親モデルであるUserモデルに情報を登録した際に子モデルのPlayerモデルにレコードを保存できるようになりました。