前回の続きでQandAサイト作成 今回は新たなテーブルを作成するところから始めます
今回は前回の投稿テーブルに紐づくテーブルを作成します!
環境 AWS Cloud9
environment type EC2
instance type t2.micro
platform ubuntu server 18.04 LTS
モデル作成
Rails が提供するModelは、
原則としてデータベース上にある
テーブルと対応しており
テーブルのデータを簡単に操作する機能を提供します
rails g model コマンド
rails g model コマンドで user に関するモデルを作成します
rails g modelの使い方
$ rails g model モデル名
AWS Cloud9 ターミナルで実行
rails g model Answer name:string content:text question:references
上記コマンドで User はモデル名
その下がデータベースのデータの構造です
name:string カラム名:データ型 投稿者の名前を保存する
content:text カラム名:データ型 内容を保存する
question:references questionテーブルとリレーション
↑どの投稿に対する回答かを管理するための設定
スペース区切りで複数 設定できます
class CreateAnswers < ActiveRecord::Migration[7.0]
def change
create_table :answers do |t|
t.string :name
t.text :content
t.references :question, null: false, foreign_key: true
t.timestamps
end
end
end
上記のマイグレーションファイルのスペルミスがないことを確認し
マイグレーションを実施します
以下の記述は カラムがnullになることを禁止
null: false
外部キー制約の設定を有効にします
foreign_key: true
レコードの作成日時と更新日時を管理するカラムを作る
t.timestamps
マイグレーション
マイグレーションは Rails で自動生成した設定内容をデータベースに反映させます
マイグレーションをもう少し、簡単に言うと
データベースのテーブルを作成・変更するための仕組みです
Railsは、マイグレーションファイルという設定ファイルを自動作成して
それをmigrationコマンドで、データベースに反映させます
以下のコマンドでデータベース設定を反映することが可能です
rails db:migrate
他のモデルとの関連を記述
1 対 多 の内容を表示できるように has_many を使用
has_many :answers
class Question < ApplicationRecord
has_many :answers, dependent: :destroy
validates :title, presence: true
validates :name, presence: true
validates :content, presence: true, length: { minimum: 5 }
end
紐づくルーティングの生成と確認
Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
# root "articles#index"
root "questions#index"
resources :questions do
resources :answers
end
end
resources :questions
↓
resources :questions do
resources :answers
とすることで questions に紐づく
answers に関するルーティングが自動生成されます
ルーティングの確認
AWS Cloud9 ターミナルで実行
rails routes
これで投稿画面に紐づくテーブル作成とルーティングまでができました!
コントローラとViewの作成
コントローラーを作成
AWS Cloud9 ターミナルで実行
rails g controller Answers
作成されたapp/controllers/answers_controller.rb
の内容を変更
class AnswersController < ApplicationController
# 回答の登録
def create
# p params
@question = Question.find(params[:question_id])
@question.answers.create(answer_params)
redirect_to question_path(@question)
end
# 回答の削除
def destroy
@question = Question.find(params[:question_id])
@answer = @question.answers.find(params[:id])
@answer.destroy
redirect_to @question, status: :see_other
end
private
def answer_params
params.require(:answer).permit(:name, :content)
end
end
Viewの変更
app/views/questions/show.html.erb
を変更します
<h1>確認画面</h1>
<p>
元の投稿タイトル:<br>
<%= @question.title %>
</p>
<p>
投稿者名:<br>
<%= @question.name %>
</p>
<p>
投稿内容:<br>
<%= @question.content %>
</p>
<h2>投稿に対する補足</h2>
<% @question.answers.each do |answer| %>
<p>
投稿者名:<br>
<%= answer.name %>
</p>
<p>
投稿内容:<br>
<%= answer.content %>
</p>
<p>
<%= link_to '削除する', [answer.question, answer],
data: { turbo_method: 'delete', turbo_confirm: '本当に削除しますか?' } %>
</p>
<% end %>
<h2>追加投稿 or 意見</h2>
<%= form_with model: [@question, @question.answers.build] do |form| %>
<div>
<%= form.label :name %><br>
<%= form.text_field :name %>
</div>
<div>
<%= form.label :content %><br>
<%= form.text_area :content %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
<%= link_to 'top', questions_path %>