Rails4でRedmine CORSを使う

ruby
Published: 2015-07-07

やりたいこと

 Cross-Origin Resource SharingでRedmineのデータを取得する

実現方法

 Redmine CORSを使い、RedmineをCORSに対応させる

やってみたこと

 READMEに記載されている方法でやってみたところ、以下の環境では動作しませんでした。

Environment:
  Redmine version                3.1.0.devel
  Ruby version                   2.2.2-p95 (2015-04-13) [x86_64-linux]
  Rails version                  4.2.3

 具体的にはプラグインのマイグレーション時に以下のエラーメッセージが出ます。

$ mogok rake redmine:plugins:migrate                   
Running 'rake redmine:plugins:migrate'...
2015-07-07T20:56:44+09:00 console[app3014.29]: An error occurred while loading the routes definition of redmine_cors plugin (/app/plugins/redmine_cors/config/routes.rb): You should not use the `match` method in your router without specifying an HTTP method.
2015-07-07T20:56:44+09:00 console[app3014.29]: If you want to expose your action to both GET and POST, add `via: [:get, :post]` option.
2015-07-07T20:56:44+09:00 console[app3014.29]: If you want to expose your action to GET, use `get` in the router:
2015-07-07T20:56:44+09:00 console[app3014.29]:   Instead of: match "controller#action"
2015-07-07T20:56:44+09:00 console[app3014.29]:   Do: get "controller#action".

 エラーメッセージに言われるがまま、以下の箇所のmatchをgetにかえると、プラグインのマイグレーションは成功します。

$ more plugins/redmine_cors/config/routes.rb 
RedmineApp::Application.routes.draw do
  match '*path', :to => 'cors#preflight', :constraints => {:method => 'OPTIONS'}
end

 ただし、ルーティングがないというエラーメッセージが出て、結局動作しません。

2015-07-07T20:00:46+09:00 app[app3012.03]: ActionController::RoutingError (No route matches [OPTIONS] "/users/current.json"):
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/rack/logger.rb:38:in `call_app'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/rack/logger.rb:20:in `block in call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/activesupport-4.2.3/lib/active_support/tagged_logging.rb:68:in `block in tagged'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/activesupport-4.2.3/lib/active_support/tagged_logging.rb:26:in `tagged'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/activesupport-4.2.3/lib/active_support/tagged_logging.rb:68:in `tagged'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/rack/logger.rb:20:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/request_id.rb:21:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/rack-1.6.4/lib/rack/methodoverride.rb:22:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/rack-1.6.4/lib/rack/runtime.rb:18:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/activesupport-4.2.3/lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/static.rb:116:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/rack-1.6.4/lib/rack/sendfile.rb:113:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/engine.rb:518:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/application.rb:165:in `call'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/railtie.rb:194:in `public_send'
2015-07-07T20:00:46+09:00 app[app3012.03]:   .bundle/gems/ruby/2.2.0/gems/railties-4.2.3/lib/rails/railtie.rb:194:in `method_missing'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/connection.rb:86:in `block in pre_process'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/connection.rb:84:in `catch'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/connection.rb:84:in `pre_process'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/connection.rb:53:in `process'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/connection.rb:39:in `receive_data'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/eventmachine.rb:187:in `run_machine'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/eventmachine.rb:187:in `run'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/backends/base.rb:73:in `start'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/server.rb:162:in `start'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/controllers/controller.rb:87:in `start'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/runner.rb:199:in `run_command'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2.2-1/lib/ruby/site_ruby/2.2.0/thin/runner.rb:155:in `run!'
2015-07-07T20:00:46+09:00 app[app3012.03]:   /opt/ruby-2.2/bin/thin:6:in `<main>'

対応策

 プラグインのroutes.rbを正しく書き換えます。

$ more plugins/redmine_cors/config/routes.rb 
RedmineApp::Application.routes.draw do
  match '*path', :to => 'cors#preflight', via: :options
end

 なお、書き換えた後に気が付いたのですが、Redmine CORSをRedmine3.0で動作させるためのプルリクエストが出てますね。。。