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


##環境
* ruby歴 初心者
* rails5
* ruby 2.4.1p111

##これはなに？
[grape](https://github.com/ruby-grape/grape) を用いた api 開発時にヘルパーメソッドを別ファイルに切り出して活用する方法のメモです。

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

##発端
[grape](https://github.com/ruby-grape/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

```

あとは、それぞれの実装

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

```

```ruby: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](https://github.com/nesquena/rabl) を組み合わせて実装しています。

```ruby: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](https://github.com/ruby-grape/grape) の実装手順に則っていたためですが `include` ではなく `helpers` でモジュールを `Mix-in` します。
`include` する場合は、ROOT を継承すれば問題ありません。

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

```ruby: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

```

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

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

```

```ruby: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
```

```ruby: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の使い方とはいったい
](http://qiita.com/shiopon01/items/fd6803f792398c5219cd)
・[rubyのモジュールを名前空間で使っているのかmix-inで使っているのか](https://ja.stackoverflow.com/questions/16960/ruby%E3%81%AE%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%82%92%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%A7%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8Bmix-in%E3%81%A7%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8B)