探し方が下手くそなのかチェックボックスを作るための記事があまりなく、メンターに教えてもらいながら実装したため復習がてら書いていきます。
間違った記述があれば教えて頂けると嬉しいです。
実装イメージ
ER図(投稿とタスクの部分のみ)
作るもの
SNS型のToDoリスト
実装したい内容
・チェックを押したあと、リロードしてもチェックが外れないようにしたい(データベースにチェック状態を保存する)
・非同期通信が出来たら”チェックを更新する”ボタンを押さずともデータベース上にチェックが保存される方法もあるが、JS部分が理解ができず断念。いつか実装させたい。
前提・実装方法
・投稿とチェックボックスに必要なマイグレーション、モデルファイルを作成
・投稿詳細ページにチェックボックスを実装したいため、postコントローラーを使う
・postコントロールのnewアクションとupdateアクションに記載
・gem 'devise'インストール済み
記載が必要なファイルメモ(自分用なので必要なファイル名にしてください)
・マイグレーションファイル
∟日付_create_tasks.rb
・モデルファイル
∟post.rb
∟task.rb
・コントローラーファイル
∟..user/posts_controller.rb
・ビューファイル
∟..user/posts/show.html.erb
∟..user/posts/new.html.erb ※新規投稿に関するファイルでチェックボックスにあまり関係なし
実装コード
①マイグレーションファイル
class CreatePosts < ActiveRecord::Migration[6.1]
def change
create_table :posts do |t|
t.string :title
t.integer :user_id
t.timestamps
end
end
end
②postモデル
class Post < ApplicationRecord
:省略
has_many :tasks, dependent: :destroy
accepts_nested_attributes_for :tasks
:
:
end
③taskモデル
class Task < ApplicationRecord
belongs_to :post
end
④postコントローラー
:省略
def new
@post = Post.new #タイトルの新規作成
@post.tasks = Array.new(10).map{ Task.new } #タスクの新規作成
end
:
:
def update #チェックボックスの更新
@post = Post.find(params[:id])
@post.update(post_params)
redirect_to post_path(params[:id])
end
:
:
private
def post_params
params.require(:post).permit(:title, tasks_attributes: [:id, :content, :complete])
end
⑤postのshowビュー
:省略
<%= form_with model: @post do |f|%>
<table class='table'>
:省略
<%= f.fields_for :tasks do |l| %>
<tr>
<td>
<%= l.check_box :complete %> <%= l.object.content %>
<%= l.hidden_field :id %>
<%= l.hidden_field :content %>
</td>
</tr>
<% end %>
<tr>
<td>
<%= f.submit "チェックを更新する", class: "btn btn-info" %>
</td>
</tr>
</table>
<% end %>
:
※tableタグとの相性が悪いらしいので後ほどブートストラップを使いつつdivタグに修正します;;
チェックボックスの実装については以上!
チェックボックスにはあまり関係ないけど新規投稿のビューファイルも載せときます。(contentが何のカラムか私が忘れそうなので笑)
⑥postのnewビュー
:省略
:
<%= form_with model: @post do |f| %>
<div class="mx-auto" style="width: 400px;">
<h2>タイトル</h2>
<%= f.text_field :title, class: "form-control" %>
</div></br>
<div class="mx-auto" style="width: 400px;">
<p>タスク</p>
<%= f.fields_for :tasks do |l|%> <!--ここに注目-->
<p><%= l.text_field :content, class: "form-control" %></p> <!--ここに注目-->
<% end %>
</div></br>
<div class="mx-auto" style="width: 300px;">
<%= f.submit '投稿', class: "btn btn-outline-primary btn-lg" %>
</div>
<% end %>
:
:
コメント
時間がないのでコードの説明は省きますが、いつか付け足していきたいです
投稿方法も「cocoonで直したほうがいいよ」と教えて頂いたので時間があればやりたい!!