Railsでロジックを書く場所を意識する
対象バージョン
- Ruby 2.2.2
- Ruby On Rails 4.2.3
ロジックを書く場所
言語を問わずMVCのフレームワークを使う時に以前からよく言われていた話として、ビジネスロジックをコントローラに書いてはいけないというのがあります。
しかし、単にコントローラを薄くすることだけを考えるとモデルがFatになってきたりするので、モデルに切り出すという事以外にもいくつかの方法を知っておく必要があります。
なかなか最適解が何かというのはわからないのですが、私はRailsで実装する場合は以下のようなパターンで実装することが多いです。
実装のパターン
1.モデルに実装する
コントローラにコードを書くのではなく、モデルにビジネスロジックを実装してコントローラを薄くします。
ただし、モデルにコードを集約し過ぎるとモデルがFatになってしまうので、本当にモデルに実装すべきかをよく考え、他の層に切り出すことも考えます。
モデルに実装するパターン
- モデルに紐付いたテーブルのレコード取得(ActiveRecordの操作)
- モデルに紐付いたテーブルをベースとした関連テーブルを含めたデータ取得
- モデルに紐付いたテーブルのデータ更新
単一テーブルの単純な更新など、シンプルな処理が該当すると思います。
2.フォームクラス
ビュー上の項目とモデルの項目に差異がある場合など、それを吸収させるものとしてモデルとビューの間にフォームクラスを差し込みます。
フォームクラスの実装例
フォームクラスはActiveModelをIncludeして実装することで、DB側に無いテーブルやテーブルの項目などの扱いが簡単になります。
例えば入力された内容のメールを送るだけのFAQ画面があった場合、以下のようにフォームクラスを定義することでバリデーションをかけることも可能です。
class FaqForm include ActiveModel::Model attr_accessor :message validates :message, presence: true, length: { maximum: 1000 } def send .... end end
ActiveModelをIncludeしているので、valid?
メソッドなども使えます。
@faq_form = FaqForm.new(faq_form_params) if @faq_form.valid? .... end
3.サービスクラス
複数のモデル操作やファイル操作などの処理を、アトミックなビジネスロジックのひとまとめの単位としてサービス層として切り出します。
サービスクラスの実装例
以下のように通常のクラスを定義します。
class DataRegistrationService def initialize .... end def registrate .... end end
4.Concern
モデルやコントローラ間でしか使わないような共通処理はそれぞれのconcernに切り出します。
concernのディレクトリ
- app/models/concerns
- app/controllers/concerns
実装例
app/model/member.rb
class Member include User end
app/model/concerns/user.rb
module User extend ActiveSupport::Concern included do attr_accessor :user_name def self.default_user_name "名無しさん" end def default_user_name? uesr_name == self.class.default_user_name end end end
5.ヘルパの活用
ビュー側で使うような見た目に関するものはヘルパで実装します。
例えば名前に敬称をつける場合など。
module UsersHelper def display_name(firstname, lastname) "#{lastname} #{first name} さん" end end
ただし、苗字 + 名前 でフルネームみたいなものは、モデル側でメソッドを実装して仮想化カラムのように扱うこともあります。
6.DraperなどのGemを使う
モデルとビューの中間に位置するようなプレゼンター層を扱えるGemもいくつか出ているのでそれを使うのも選択肢としてあると思います。
新しいことや難しい課題に挑戦することにやりがいを感じ、安定やぬるい事は退屈だと感じます。 考えるより先に手が動く、肉体派エンジニアで座右の銘は諸行無常。 大事なのは感性、プログラミングにおいても感覚で理解し、感覚で書きます。
TAG
- Android
- AWS
- Bitrise
- CodePipeline
- Firebase
- HTML
- iOS
- IoT
- JavaScript
- KPI
- Linux
- Mac
- Memcached
- MGRe
- MGReのゆるガチエンジニアブログ
- MySQL
- PHP
- PICK UP
- PR
- Python
- Ruby
- Ruby on Rails
- SEO
- Swift
- TIPS
- UI/UX
- VirtualBox
- Wantedly
- Windows
- アクセス解析
- イベントレポート
- エンジニアブログ
- ガジェット
- カスタマーサクセス
- サーバ技術
- サービス
- セキュリティ
- セミナー・展示会
- テクノロジー
- デザイン
- プレスリリース
- マーケティング施策
- マネジメント
- ラボ
- リーンスタートアップ
- 企画
- 会社紹介
- 会社紹介資料
- 勉強会
- 実績紹介
- 拡張性
- 採用
- 日常
- 書籍紹介
- 歓迎会
- 社内イベント
- 社員インタビュー
- 社長ブログ
- 視察
- 開発環境