掲示板の一覧機能の作成
掲示板の一覧機能の作成の確認ポイント
・Boardモデルのバリデーション
validates :title, presence: true, length: { maximum: 数 } validates :body, presence: true, length: { maximum: 数 }
・Userモデル
has_many :boards, dependent: :destroy
dependent: :destroyを追加することで、 「親モデルを削除する際に、その親モデルに紐づく「子モデル」も一緒に削除できる」ようになります。 例えばユーザーが退会した場合、そのユーザーが投稿した記事も全て消えるように設定するのであれば、必須な知識。
・N+1問題 データベースからデータを取り出す際に、たくさんのSQLを発行して、アプリケーションの動作が重くなってしまう問題だ。 原因は、複数のテーブルに関連(アソシエーション)があるからです。あるテーブルの一覧を取得するために、SELECTを一度実行すると、そのテーブルに関連したテーブルのデータを取得するために、またSELECTが実行されてしいる。
includesメソッドで関連付けを一括読み込みをする includesは、関連助けられたテーブルのデータを参照するメソッドだ。このメソッドを使うと、あるモデルからデータを取得する際に、関連付けされたモデルのデータもいっしょに取得してくれる。
class BoardsController < ApplicationController def index @boards = Board.all.includes(:user).order(created_at: :desc) end end
・掲示板のパーシャルをrenderしていること collectionをeachするより、部分テンプレートをrenderで回すほうがパフォーマンスがよく、以下の様にコード量が減り、可読性が上がる。 app/view/boards/index.html.erb
<%= render @boards %>
・Boardモデルのuser_idに外部キー制約がついていること
class CreateBoards < ActiveRecord::Migration[5.2] def change create_table :boards do |t| t.string :title, null: false t.text :body, null: false t.references :user, foreign_key: true # このようにreferences型になっていればOK t.timestamps end end end
外部キー制約をつけることで、存在しないユーザーのIDが登録されて、不整合なデータが発生することをDB側から拒否できる。
・アクセス制御をさせたいコントローラー(BoardsControllerやUsersController)で個別にbefore_actionを記載するのではなくて、継承元の親クラスであるApplicationControllerに記載することで処理を共通化させる
class ApplicationController < ActionController::Base before_action :require_login private def not_authenticated redirect_to login_path, warning: t('defaults.message.not_authenticated') end end
これで他のControllerを追加で実装する際にも、アクセス制御の処理を忘れずに適用させることができる。 ログイン画面ではアクセス制御を適用させたくないのでUserSessionsContollerにはskip_before_actionで継承元のbefore_actionで定義した処理を無効化させることができる。 not_authenticatedメソッド ログインできなかった(認証されなかった)場合に、このメソッドに記述した処理が行われる。
参考文献