[Rails] 掲示板の新規作成機能を実装する

学習記録

はじめに

掲示板作成機能を実装していきます。

作業の流れ

  • 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

buildnewのエイリアスです。

慣習的にアソシエーション先のモデルを作成する時は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のブロック中でlabelnameを指定せずに、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' %>

コメント

タイトルとURLをコピーしました