トレタ開発者ブログ

飲食店向け予約/顧客台帳サービス「トレタ」、モバイルオーダー「トレタO/X」などを運営するトレタの開発メンバーによるブログです。

トレタにJOINして勉強になったRailsに関する3つを紹介

この記事はトレタ Advent Calendar 2020の22日目の記事です。

はじめまして。2020年3月からJOINしたサーバーサイドエンジニアをしている @shiroemons です。

Appleから AirPods Max が発表されて、SonyのWH-1000XM4を即購入して、ノイズキャンセリング機能と2台の機器に同時接続できるマルチポイント機能に感動している今日このごろです。 マイク性能に関しては、手持ちのAirPodsの方が良さそうなので、ビデオ会議の時は切り替えが必要なのが残念ポイントでした...

本日は、私がトレタにJOINして、勉強になったRailsに関する3つを紹介します。

config/routes.rb のファイル分割

1つ目は、巨大になりがちなルートファイル(config/routes.rb)を複数のファイルに分割するTipsです。

↓でconfig/routes.rbにdrawメソッドを追加することでルーティングの内容を別ファイルに分割できるようになります。

# config/routes.rb
class ActionDispatch::Routing::Mapper
  def draw(routes_name)
    instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
  end
end

Rails.application.routes.draw do
  draw :admin
end

# config/routes/admin.rb
get :foo, to: 'foo#bar'

DHHのgistもあります。

こちらは、Rails 4.0がリリースする前に一度取り込まれた機能になりますが、revertされました。 ところが、最近リリースされたRails 6.1で、この機能が復活しました🎉

Rails 6.1からは、今回のTipsは不要になります。

# config/routes.rb
Rails.application.routes.draw do
  draw(:admin)
end

# config/routes/admin.rb
get :foo, to: 'foo#bar'

Rails Guidesもすでに用意されています。(日本語はまだかな)

guides.rubyonrails.org

ルートファイルを分割したい場合は、試してみてください!

APIドキュメントツール apipie-rails

ここ最近のRailsの役割は、APIで利用されることが増えてきました。 必要になってくるのは、エンドポイントは何で、どんなパラメーターが必要で、どんなエラーが発生するのかなどのドキュメントが大事になってきます。

そこで重宝されるのは、REST API向けのドキュメント生成ツールのapipie-railsです。

github.com

ここでは、設定方法などは省略します。設定方法などは、GemのREADMEをご参照ください。

コントローラーのメソッドの上部に、HTTPメソッドやエンドポイント、パラメーター、エラーなどの説明を記載することで簡単にAPIドキュメントが残すことができます。 学習コストが少なくすぐに利用することができます。

サンプルコード

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  api :GET, '/users', 'ユーザ一覧を返します'
  def index
    @users = User.all
  end

  api :GET, '/users/:id', '指定したIDのユーザー情報を返します'
  param :id, :number, require: true, desc: 'ユーザーID'
  error code: 404, desc: 'Not Found'
  example <<-EOS
  {
    "id": 1,
    "name": "hoge",
    "created_at": "2020-12-17T05:23:18.135Z",
    "updated_at": "2020-12-17T05:23:18.135Z",
  }
  EOS
  def show
    #...
  end
  
  #...

画面キャプチャ

f:id:shiroemons:20201221164343p:plain
サンプル画面

このような、ドキュメントが簡単に生成することができます。

apipie-railsは、Swagger形式(OpenAPI 2.0)のJSON出力が可能です。

rake apipie:static_swagger_json

GemのREADME にも記載があるので参照してみてください。

APIドキュメントの管理は、苦労したことがあるので簡単に生成できるのでとても感動したので、紹介してみました。

コールバッククラス

Railsを運用していくとどうしてもコールバック処理が煩雑かつ、複雑になりがちです。 そんな時は、Railsガイドにも載っているコールバッククラスを利用します。

railsguides.jp

サフィックスにDispatcherを付けてコールバッククラスを利用しています。 主な用途としては、複数のモデルから共通の非同期処理を行う Worker の呼び出しに使用しています。

以下は、店舗の席情報に変更が行われた際、非同期処理で席在庫を再計算するサンプルコードです。

# app/callbacks/restaurant_table_stock_manager_dispatcher.rb
class RestaurantTableStockManagerDispatcher
  def after_commit(record)
    rebuild_stocks_async(record)
  end

  private

  def rebuild_stocks_async(record)
    # 非同期処理(Worker)呼び出し
  end
end

# app/models/restaurant_table.rb
class RestaurantTable < ActiveRecord::Base
  after_commit RestaurantTableStockManagerDispatcher.new, on: [:update]
end

このようにafter_commit等のコールバックに対応するメソッドをパブリックメソッドとして定義します。 引数にはコールバックを呼び出すキッカケになったオブジェクトが渡されます。

コールバッククラスは、コールバック処理すべてをコールバッククラスにするのではなく、 複数のモデルで同一の処理を行う場合や、複雑な処理を行っているものなどの機能単位に切り出せるものに留めておくのが良いかと思います。

コールバッククラス自体は、目新しいものではありませんがバリバリ活用していたので、紹介したかったところです。

おわりに

1つ1つは、目新しいものではないですが、実際に利用し活用していますよという発信の意味を込めて紹介してみました。

トレタに少しでも興味を持っていただいた方がいれば、ぜひ遊びに来てください! 仲間を募集しています!

corp.toreta.in

© Toreta, Inc.

Powered by Hatena Blog