9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Grapeでヘルパーメソッドを別ファイルに切り出して使う方法

Posted at

##環境

  • ruby歴 初心者
  • rails5
  • ruby 2.4.1p111

##これはなに?
grape を用いた api 開発時にヘルパーメソッドを別ファイルに切り出して活用する方法のメモです。

「ここ間違ってるよ!」
「ここはこうした方がいいんじゃん?」
などなどあればコメントお願い致しますm(_ _)m

##発端
grape を用いた api 開発を進めていく中で、共通の処理、独自エラーなどをルートファイルに書きまくって
fat & unreadable になったため切り出しを考えました。

ディレクトリ状況としては下記のとおりです。

├── app
│   ├── apis
│   │   └── api
│   │       ├── concerns
│   │       ├── root.rb
│   │       └── v1
│   │           └── sample.rb

##実装
はまった部分はありましたが、先に結果を書きます。
※はまった部分に関しては、後述しますので興味があれば!

まず、共通処理部分をモジュールとして切り出します。
今回、バージョンごとのヘルパーメソッドとするので
モジュール名は V1::Helpers::AuthenticateHelper とします。
名前空間を V1::Helpers としているので
下記のように配置します。

├── app
│   ├── apis
│   │   └── api
│   │       ├── concerns
│   │       ├── root.rb
│   │       └── v1
│   │           ├── sample.rb
│   │           └── helpers
│   │           		└── authenticate_helper.rb

あとは、それぞれの実装

authenticate_helper.rb
module V1
	module Helpers
		module AuthenticateHelper
			def authenticate!
				# someting proccess...
			end
			
			def current_user
				# someting proccess...
			end
		end
	end
end

root.rb
class API::ROOT < Grape::API
	helpers V1::Helpers::AuthenticateHelper # -> ここに追加
	
	version "v1", using: :path
	format :json
	formatter :json, Grape::Formatter::Rabl
	prefix "api"
	
	namespace :sp do
	  mount API::V1::Sample
	end
	
	# something method & proccess
end

実際の利用シーン
rable を組み合わせて実装しています。

sample.rb
class API::V1::CalendarPhotoAssets < Grape::API
    before { authenticate! }

    get :samples, rabl: "samples/index" do
      @samples = current_user.samples
    end
end

##名前空間とMix-in
モジュールには名前空間Mix-inという複数の役割があるという理解ができておらずハマってしまいました。
自分はMix-inのみで考えていたため、うまく読み込めずメソッドをコールしても「そんなメソッドねえよ」と怒られるばかりでした。
V1::Helper の部分は名前空間なのでMix-inする対象とは何も関係ありません。

##GrapeにおけるMix-in
最初、 include V1::Helpers::AuthenticateHelper と宣言していましたが、エラーしていました。
これは grape の実装手順に則っていたためですが include ではなく helpers でモジュールを Mix-in します。
include する場合は、ROOT を継承すれば問題ありません。

##おまけ
ヘルパーモジュールが増えてくると
下記のように箇条書きされていき fat 要因になります。

root.rb
class API::ROOT < Grape::API
	helpers V1::Helpers::AuthenticateHelper
	helpers V1::Helpers::Sample1Helper
	helpers V1::Helpers::Sample2Helper
	helpers V1::Helpers::Sample3Helper
	
	version "v1", using: :path
	format :json
	formatter :json, Grape::Formatter::Rabl
	prefix "api"
	
	namespace :sp do
	  mount API::V1::Sample
	end
	
	# something method & proccess
end

なので、宣言自体を切り出して
1行の宣言で済むようにします。
※ namespace名と同じファイル名にしてください

├── app
│   ├── apis
│   │   └── api
│   │       ├── concerns
│   │       ├── root.rb
│   │       └── v1
│   │           ├── sample.rb
│   │           ├── helpers.rb # -> ここに namespace名.rb を追加
│   │           └── helpers
│   │           		└── authenticate_helper.rb

helpers.rb
module V1
	module Helpers
		# helpers は grape だけなので include で Mix-inします
		include V1::Helpers::AuthenticateHelper
		include V1::Helpers::Sample1Helper
		include V1::Helpers::Sample2Helper
		include V1::Helpers::Sample3Helper
	end
end
root.rb
class API::ROOT < Grape::API
	helpers V1::Helpers
	
	version "v1", using: :path
	format :json
	formatter :json, Grape::Formatter::Rabl
	prefix "api"
	
	namespace :sp do
	  mount API::V1::Sample
	end
	
	# something method & proccess
end

##学んだこと
・モジュールの役割について
・Grape における Mix-in

##参考
RubyのModuleの使い方とはいったい

rubyのモジュールを名前空間で使っているのかmix-inで使っているのか

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?