Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ApplicationController の継承を分割してエラーを減らした話/dividing-application-controller

ApplicationController の継承を分割してエラーを減らした話/dividing-application-controller

Masatoshi Moritsuka

March 01, 2024

More Decks by Masatoshi Moritsuka

Other Decks in Technology


  1. 自己紹介 森塚 真年 GitHub: @sanfrecce-osaka Twitter(X): @sanfrecce_osaka Qiita: @sanfrecce_osaka from:

    大阪府枚方市 趣味: コミュニティ・勉強会 株式会社エンペイ Ruby3.2/Rails7.0 Node.js v18/Vue.js 3.3/Vuetify 3.4
  2. class ApplicationController < ActionController::Base # 略 # if/unless/only/except オプション 😇

    before_action :store_referrer, except: :raise_not_found, if: :devise_controller? before_action :require_functional!, if: :user_signed_in? before_action :set_cache_control_defaults # skip_before_action 😇 skip_before_action :verify_authenticity_token, only: :raise_not_found # 略 end
  3. # AC を継承した AC 😇 class Disputes::BaseController < ApplicationController #

    略 # 継承先の AC で skip_before_action 😇 skip_before_action :require_functional! before_action :set_body_classes before_action :authenticate_user! before_action :set_cache_headers # 略 end
  4. # AC を継承した AC を継承した AC 😇 class Settings::ApplicationsController <

    Settings::BaseControl before_action :set_application, only: [:show, :update, :destroy, :regenerate] before_action :prepare_scopes, only: [:create, :update] # 略 end
  5. module Settings module TwoFactorAuthentication class ConfirmationsController < BaseController # 略

    # 具象コントローラで skip_before_action 😇 skip_before_action :require_functional! before_action :require_challenge! before_action :ensure_otp_secret # 略 end end end
  6. module や namespace で 境界を区切る resources :payments, module: :payments do

    resources :histories end namespece: :account do resources :settings end
  7. module Accounts class ApplicationController < ActionController::Base # 重複は許容。共通化したい場合は module や

    concern に切り出す before_action :validate_params before_action :authenticate_account! before_action :authorize! # 略
  8. ユースケースごとに異なる場合 module Payments class HistoriesController < ApplicatonController # 略 private

    # 共通の振る舞いがない場合はオーバーライド def validate_params # 具象コントローラ個別の処理 end def authorize! super # 共通処理を呼び出す # 具象コントローラ個別の処理 end
  9. # param を使って指定すると /payments/{payment_id} になるが resources :payments, param: :payment_id, module:

    :payments do # ここが /payments/{payment_payment_id} になってしまう  resources :histories end
  10. # これでもいけるけど # module: :payments を 2回 書くのも嫌なので・・・ resources :payments,

    param: :payment_id, module: :payments resources :payments, only: [], module: :payments do resources :histories end
  11. scope module: :payments do # 最終的にこんな形に resources :payments, param: :payment_id

    resources :payments, only: [] do resources :histories end end