タグ機能をCRUD2つ実装して実現しているイメージです。
「授業に受講している学生を登録したい」「コーディネートに洋服の情報を紐づけたい」「タグ機能をseedファイルを使わずに実装したい」etc...
こういったモデルの多対多の関連付けをした投稿を実装したい方は一度読んでみてください。
【 目次 】
- 開発環境と前提
- 概要と方針
- 実装するコード
【 開発環境と前提 】
< 開発環境 >
・ruby 3.0.4
・rails 6.1.6
< 前提 >
・Studentモデル、コントローラーのCRUD機能実装済み
・カラムはname/string型
【 概要と方針 】
< 概要 >
・lesson投稿時に、登録されている学生を複数選択して投稿できるようにする。
< 方針 >
・Lessonモデル、コントローラーのCRUD実装
・カラムはname/string型
・中間テーブルの作成
・アソシエーションの記述
・viewの記述
< 完成図 >
※また貼っときます。
【 実装するコード 】
lessonモデルとlesson-studentの中間テーブルを作成。
$rails g model Lesson name:string
$rails g model Lesson_student_relation student:references lesson:references
$rails db:migrate
アソシエーションを記述する。
class LessonStudentRelation < ApplicationRecord
belongs_to :student
belongs_to :lesson
end
class Student < ApplicationRecord
#nameカラムが空でないことを指定
validates :name, presence: true
#studentsテーブルから中間テーブルに対する関連付け
has_many :lesson_student_relations, dependent: :destroy
#studentsテーブルから中間テーブルを介してLessonsテーブルへの関連付け
has_many :lessons, through: :lesson_student_relations, dependent: :destroy
end
class Lesson < ApplicationRecord
#nameカラムが空でないことを指定
validates :name, presence: true
#Lessonsテーブルから中間テーブルに対する関連付け
has_many :lesson_student_relations, dependent: :destroy
#Lessonsテーブルから中間テーブルを介してStudentsテーブルへの関連付け
has_many :students, through: :lesson_student_relations, dependent: :destroy
end
lessonsコントローラーの作成。
rails g controller lessons
コントローラーの中身を記述。
class LessonsController < ApplicationController
def index
@lessons = Lesson.all
end
def new
@lesson = Lesson.new
end
def create
lesson = Lesson.new(lesson_params)
if lesson.save
redirect_to :action => "index"
else
redirect_to :action => "new"
end
end
def show
@lesson = Lesson.find(params[:id])
end
def edit
@lesson = Lesson.find(params[:id])
end
def update
lesson = Lesson.find(params[:id])
if lesson.update(lesson_params)
redirect_to :action => "show", :id => lesson.id
else
redirect_to :action => "new"
end
end
def destroy
lesson = Lesson.find(params[:id])
lesson.destroy
redirect_to action: :index
end
private
def lesson_params
params.require(:lesson).permit(:name, student_ids: [])
end
end
ルートの記述
Rails.application.routes.draw do
# ~中略~
resources :students
resources :lessons
# ~中略~
end
viewの記述。授業投稿ページ。editも同様に書いてください。
<%= form_for @lesson do |f| %>
<%= f.label :name %>
<%= f.text_field :name, :size => 140 %>
<div class='form-group'>
<%= f.collection_check_boxes(:student_ids, Student.all, :id, :name) do |student| %>
<div class='form-check'>
<%= student.label class: 'form-check-label' do %>
<%= student.check_box class: 'form-check-input' %>
<%= student.text %>
<% end %>
</div>
<% end %>
</div>
<%= f.submit '登録' %>
<% end %>
<%= link_to "授業一覧へ", lessons_path %>
授業一覧ページ。
<%= link_to "生徒一覧へ", students_path %>
<%= link_to "新規授業登録する", new_lesson_path %>
<br>
<% @lessons.each do |l| %>
<%= l.name %>
<%= link_to "詳細", lesson_path(l.id) %>
<%= link_to "編集", edit_lesson_path(l.id) %>
<%= button_to "削除", lesson_path(l.id), method: :delete %>
<% end %>
授業詳細ページ。
<h4><%= @lesson.name %></h4>
<% @lesson.students.each do |s| %>
<span><%= s.name %></span>
<% end %>
<%= link_to "編集する", edit_lesson_path(@lesson.id) %>
<%= link_to "授業一覧へ", lessons_path %>
生徒の詳細ページに参加授業一覧を表示。
<h3>Student詳細</h3>
<%# ~中略~ %>
<h5>参加授業</h5>
<% @student.lessons.each do |l| %>
<p><%= l.name %><p>
<% end %>
<%# ~中略~ %>
一旦以上です。ちょっと爆速で書いたので、抜けもれ・エラーがあれば遠慮なくFBください。