LoginSignup
1
0

More than 1 year has passed since last update.

Railsの苦しさと1対多の登録

Last updated at Posted at 2022-12-05

はじめに

 個人開発を通してRailsの一連の流れというかスタイルがわかってきた。ルーティングを設定し、modelをつくり、コントローラーをつくり、ビューファイルを書く。けれども調べてもわかりづらいことがあったりして大変だった。1対多の登録がそれだった。

1対多とは

 
 1対多とは、あるテーブルのひとつのレコードが別のテーブルの複数のレコードと関係している状態である。例えば一人の図書館ユーザーが複数の本を借りているとすると、ユーザーと本は1対多の関係にあると言える。

 私のアプリでは1日の日報と作業内容が1対多の関係にあった。一枚の日報に対して複数の作業を入力していくのだ。モデルの関係性の設定はできたし、バリデーションの設定もできた。しかし、いかにしてその要素を一括で登録するのかが難しかった。

複数の項目を一括で登録する

 登録画面は問題なくかけた。

app/views/reports/_form.html.erb
<!-- 略 -->
        <%= form_with model: @report, local: true do |f| %>
          <div class="form-group mb-4">
            <label for="label-report" class="form-label">登録日</label>
            <% if @report.reported_on.nil? %>
              <%= f.date_field :reported_on, {class: "form-control" ,value:Date.today }%>
            <% else %>
              <%= f.date_field :reported_on, {class: "form-control"} %>
            <% end %>
          </div>
          <div class="form-group mb-4">
              <div class="form-row">
                <div class="col-3 col-md-3">ジャンル</div>
                <div class="col-6 col-md-6">やったこと</div>
                <div class="col-2 col-md-2">時間</div>
                <div class="col-1 col-md-1">-</div>
              </div>
              <div id="report_items">
                  <%= f.fields_for :report_items do |item| %>
                    <%= render "report_item_fields", f: item %>
                  <% end %>
                  <div class="row links" id="intersect-point">
                    <div class="col-12 text-center">
                      <%= link_to_add_association "", f, :report_items ,\
                      :"data-association-insertion-node" => "#intersect-point" ,class: 'fas fa-plus' %>
                    </div>
                  </div>                   
              </div>  
          </div>
          <div class="form-group mb-4">
          <label for="label-report" class="form-label">コメント</label>
            <%= f.text_area :content,class: "form-control form-control-sm" ,size: "2x3"%></p>
          </div>
          <%= f.submit "登録", {class: "btn-primary btn-lg"}%>
        <% end %>
<!-- 略 -->
app/views/reports/_report_item_fields.erb
<div class="form-row nested-fields">
    <div class="my-2 col-3 col-md-3">
			<%= f.text_field :genre_name ,{:class => 'form-control' ,:list => 'datalistOptions3', :id => 'exampleDataList3' , :value => get_genre_name(f.object.genre_id) } %>
			<datalist id="datalistOptions3">
			<% @select_genre.each do |genre| %>
				<option value= <%= genre.name %> >
			<% end %>
			</datalist>
    </div>
		<div class="my-2 col-6 col-md-6">
    	<%= f.text_field :content,class: "form-control form-control-sm w-100"%>
		</div>
    <div class="my-2 col-2 col-md-2">
			<%= f.text_field :work_hours,class: "form-control form-control-sm w-100"%>
		</div>
    <div class="col-1 col-md-1 d-flex justify-content-center align-items-center">
			<%= link_to_remove_association "", f  ,\
    	class: 'fas fa-trash-alt' %>
		</div>
</div>

ここで、reportが日報であり、report_itemsが作業内容である。
report_itemsは複数登録が可能であり、+とか-マークで項目を増やせる。これはcocoonというgemを使っているが、これはまた別のときに書きたい。

fields_for を使うことで、異なるモデルも編集できる。つまりはreportだけでなく`report_itemsも編集可能になるのだ。

これで登録ボタンを押すと、パラメータがコントローラに渡される。これを解析するのがちょっと面倒だった。

binding.pryでの確認

 渡されるデータがどのような形であるのか、知る必要があった。binding.pryを使った。これをコードの途中で挟むことで、デバック作業を行える。時を停止し、変数の中のデータを確認したりできる。

createアクション中に挟む。

app/controllers/reports_controller.rb
class ReportsController < ApplicationController
# 略

  def create
   binding.pry
  end

end

paramsの中に何がはいっているのか。

pry(#<ReportsController>)> params
=> <ActionController::Parameters {"authenticity_token"=>"qyEey4ZqOElVMESUggFdPNOjsgsmDDK7yLZDtwuxv9yxVsI8kPkzspTbkVhyYyeppK1qR/mhG7ed1sjDR95wDA==", "report"=><ActionController::Parameters {"reported_on"=>"2021-10-17", "report_items_attributes"=>{"0"=>{"genre_id"=>"1", "content"=>"a", "work_hours"=>"3"}, "1"=>{"genre_id"=>"", "content"=>"", "work_hours"=>""}, "2"=>{"genre_id"=>"", "content"=>"", "work_hours"=>""}}, "content"=>"test"} permitted: false>, "commit"=>"登録", "controller"=>"reports", "action"=>"create"} permitted: false>

 ここからの処理は過去の記事にも書いている。

 そうして今に至る。

苦しさとの向き合い方

 Railsに限らないことだが、この世はわからないことが多い。苦しい。わかるまで調べるのも一つの手だし、諦めるのも良いかもしれない。なんにせよ個人開発だ。継続を第一として付き合っていこう。

 私はこのような類の苦しみはわりと心地が良い。

  

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0