はじめに
掲示板作成機能を実装していきます。
作業の流れ
- UserモデルにBoardモデルとのアソシエーションを追加
- ルーティングの設定
- コントローラの作成
- ビューファイルの作成
UserモデルにBoardモデルとのアソシエーションを追加
user.rbに、アソシエーションの定義を追記します。
has_many :boards, dependent: :destroy
ルーティングの設定
掲示板作成のためのアクションを追加しましょう。
resources :boards, only: %i[index new create]
コントローラに追記
class BoardsController < ApplicationController
def index
@boards = Board.all.includes(:user).order(created_at: :desc)
end
def new
@board = Board.new
end
def create
@board = current_user.boards.build(board_params)
if @board.save
redirect_to boards_path, success: t('defaults.message.created', item: Board.model_name.human)
else
flash.now['danger'] = t('defaults.message.not_created', item: Board.model_name.human)
render :new
end
end
def show
@board = Board.find(params[:id])
end
private
def board_params
params.require(:board).permit(:title, :body)
end
end
コードを紐解く
# GOOD アソシエーション活用
@board = current_user.boards.build(board_params)
# BAD 初期化した後に値を代入
@board = Board.new(board_params)
@board.user_id = current_user.id
# BAD 初期化する際のパラメータをmerge
Board.new(board_params.merge(user_id: current_user.id))
Build
= new
build
はnew
のエイリアスです。
慣習的にアソシエーション先のモデルを作成する時はbuildが使われることが多いです。
初期化: 人為的に最初に与える値のこと。新規に作成することを指す
ビューファイルの作成
掲示板新規作成画面
<div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<h1><%= t('.title') %></h1>
<%= render 'form', { board: @board } %>
</div>
</div>
</div>
掲示板フォーム画面のパーシャル
<%= form_with model: board, local: true do |f| %>
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, class: 'form-control', rows: 10 %>
</div>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
コードを紐解く
フォームのテキストエリアの入力幅はstyleで指定するのではなく、rows:
で設定しましょう。
# BAD styleで高さを指定して、入力幅を設定している
<%= f.text_area :body, class: 'form_control', style: 'height: 200px', row: 10 %>
# GOOD styleを使用せずに、rows: オプションで入力幅を設定している
<%= f.text_area :body, class: 'form_control', rows: 10 %>
rows
: 入力欄の高さを行数で指定する。入力内容がこの高さを超えた場合は、入力欄にスクロールバーが表示される。
form_with
のブロック中でlabel
にname
を指定せずに、form_with
の自動付与機能を使いましょう。
# BAD f.labelのname属性を、name:で個別に指定している
<%= form_with model: board, local:ture do |f| %>
<div class="form-group">
<%= f.label :title, name: 'title' %>
<%= f.text_field :title, class: form_control' %>
</div>
# GOOD f.labelのname属性を、form_withの自動付与に任せている
<%= form_with model: board, local: true do |f| %>
<div class="form_group">
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
</div>
ヘッダーの掲示板作成画面へのリンクを編集
<%= link_to t('boards.new.title'), new_board_path, class: 'dropdown-item' %>
コメント