seedファイルとhidden_fieldを使って別テーブルに保存する方法
やりたいこと
- seedファイルに用意したデータをテーブルに入れる
- それをビューに表示させる
- ビューに表示された文字列をクリックすると、別のテーブルに保存される
完成のビューイメージ
seedファイルの準備
初期データをseed.rb
に記述します。
Activity
モデルに入れたいのでActivity.insert_all
に続けて、配列の中にハッシュを記述する形にします。
idは後からビューの表示などに使うので数字を振っておきます。
すべて記述できたらターミナルでrails db:seed
します。
ポイント!
seed.rb
に変更があった場合にそのままrails db:seed
してしまうと、すでにseedしているデータと重複してしまいます。そのため、冒頭にActivity.destroy_all
とし、毎回リセットさせるようにします。
Activity.destroy_all
Activity.insert_all([
# ごみのセクション
{ id: 1, activity: 'レジぶくろをもらわない' },
{ id: 2, activity: 'マイエコバッグを使う' },
{ id: 3, activity: 'マイはしを持ち歩く' },
{ id: 4, activity: 'いらなくなったものを他の人にゆずる' },
{ id: 5, activity: '分べつしてごみをすてる' },
{ id: 6, activity: 'リサイクルされた物を買う' },
{ id: 7, activity: 'ごみ拾いにさんかする' },
{ id: 8, activity: 'ペットボトルのキャップとラベルをはずして分べつする' },
{ id: 9, activity: 'こわれたものはしゅうりして使う' },
{ id: 10, activity: '「もったいない」をさがす' },
# スマートムーブのセクション
{ id: 11, activity: '近くの場所に行くときは自転車に乗る' },
{ id: 12, activity: '近くの場所に行くときは歩く' },
{ id: 13, activity: '電車に乗る' },
{ id: 14, activity: 'バスに乗る' },
# 学習のセクション
{ id: 15, activity: '「生物多様性」について調べる' },
{ id: 16, activity: '「地球温暖化」について調べる' },
{ id: 17, activity: '「ごみ問題」について調べる' },
{ id: 18, activity: '「絶めつ危ぐ種」について調べる' },
{ id: 19, activity: '「3R」について調べる' },
{ id: 20, activity: '「オゾンそう」について調べる' },
{ id: 21, activity: '「砂ばく化」について調べる' },
])
ビューの記述
class ActivitiesController < ApplicationController
def new
@activities = Activity.all
end
end
<div class="my-5">
<% @activities[0,9].each do |activity| %>
<div class="flex align-center my-7">
<h4 class="text-md text-gray-800 ml-4 hover:border-b-2 hover:border-green-500">
<%= activity.activity %>
</h4>
</div>
<% end %>
</div>
Activity
モデルからインスタンスを生成したデータをeachメソッドで展開して表示します。
このとき、前述の完成イメージのようにカテゴリごとに表示させたいので手動で分けます。
new.html.erb
の2行目に注目です(なぜファイル名がindexではなくnewなのかは後述)。
@activities
の後ろの[0,9]
は「配列の0番目から9個分取得する」という意味を表します。
つまり、id:1からid:10までを取得しています。
そのため、次のカテゴリのかたまりをビューで表示させるためには
<div class="my-5">
<% @activities[10,4].each do |activity| %>
<div class="flex align-center my-7">
<h4 class="text-md text-gray-800 ml-4 hover:border-b-2 hover:border-green-500">
<%= activity.activity %>
</h4>
</div>
<% end %>
</div>
このように[10,4]
と記述して、「配列の10番目から4個分取得」し、
id:11からid:14までを取得させます。
詳細はRuby公式ドキュメントのself[start, length]を確認しましょう
DBへの保存どうやるか
さて、上記の手順で表示させた文字列を取得して、ユーザーと紐づけてデータベースに保存させたいわけです。
今回、Railsのヘルパーメソッドhidden_field
を使用します。
<%= f.hidden_field :activity_id, :value => activity.id %>
第一引数にパラメーター名(シンボル)、第二引数にvalueとして受け渡します。
これ、htmlだとどうなってるかというと、
<input value="1" type="hidden" name="activity[activity_id]" id="activity_activity_id">
(valueに1が入っているのは例です。idが5だと、ここは5になります)
これと、form_with
でフォームの形を作ると、下のように記述ができます。
class ActivitiesController < ApplicationController
def new
@user_activity = Activity.new
@activities = Activity.all
end
def create
@user_activity = UserActivity.new({ activity_id: params[:activity][:activity_id], user_id: current_user.id })
@user_activity.save
end
end
<div class="my-5">
<% @activities[10,4].each do |activity| %>
<%= form_with model: @user_activity, path: user_activities_path, local: true do |f|%>
<div class="flex align-center my-7">
<%= button_tag type: 'submit' do %>
<svg>
# 省略
</svg>
<% end %>
<h4 class="text-md text-gray-800 ml-4 hover:border-b-2 hover:border-green-500">
<%= activity.activity %>
</h4>
<%= f.hidden_field :activity_id, :value => activity.id %>
</div>
<% end %>
<% end %>
</div>
先ほどのファイル名をnew
としている話ですが、この画面でcreateしたいからnew
としていたんです。アクションとビューを対応させたほうがわかりやすいかと思いまして。
問題点
今のところ、seedファイルのレコードを増やすつもりがないのでこの方法でも問題ないと思っています。
しかし、今後増やす、となった場合に、カテゴリごとにビューを分けていることもありメンテナンスしにくい点と、大規模データには対応できないというのが問題点ですね。
Discussion