ActiveResourceでRedmine REST使ってみた
今更だけどActiveResource使ってみた.
ActiveResourceっていうのは,Railsのレールに完全に乗っかったモデルがあってREST APIが定義されていたら,別RailsアプリからでもActiveRecordみたいに触れる機能らしい.
ActiveResource腰にRedmineを触ることがあったのでメモがてらまとめ.
参考サイトは以下
使い方
今回はRails5でためす,Rails5で使う際には,masterのを使う必要があるみたいなのでGemfileに指定.
gem 'activeresource', github: 'rails/activeresource', branch: 'master'
参考サイト通りRedmineとつなげる.
class RedmineBase < ActiveResource::Base self.site = 'https://redmine.example' self.headers['X-Redmine-API-Key'] = 'hogee' self.format = :xml end
あとは,同名のモデルを作ればいい(migrateなどは不要なのでおもむろにmodelを追加する形でもいい)
class Project < RedmineBase end Project.find(:all)
ここで罠がある.
unicornみたいな複数スレッドを回すパターンだと何故か self.headers[X-Redmine-API-Key'] の中身が消失し,認証に失敗し続けるという事があったので,何とかして回避させる.
class RedmineBase < ActiveResource::Base
self.site = 'https://redmine.example'
self.headers['X-Redmine-API-Key'] = 'hogee'
self.format = :xml
def self.configure
self.site = 'https://redmine.example'
self.headers['X-Redmine-API-Key'] = 'hogee'
self.format = :xml
end
end
こうした上で,application_controller.rbに
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_redmine_base
private
def configure_redmine_base
RedmineBase.configure
end
end
こうやって書くと毎回セットアップされるようになるので良さそう.
モデル名とRESTのPathが一致しない場合には,prefixを設定する.
class Membership < RedmineBase
def self.set_project(project_id)
self.prefix = "/projects/#{project_id}/"
end
end
Project.find(:all)で一度に取れるプロジェクト数などがxml apiの関係でデフォルト25件になっている.*1
全件取りたいときはこんな感じ
@projects = []
page_index = 1
loop do
projects = Project.find(:all, params: {page: page_index})
page_index = page_index + 1
break if projects.count == 0
@projects = @projects.concat(projects)
end
limitは最大100件なので,paramsにlimit: 100とすればもう少しリクエストを少なくできる.クエリーにつけるオプションなどもparamsに引っ付ければいい.
使ってみて
whereなどが使えないのでActiveRecordかと思いきやそうでもないので意外と使いにくい.今回の利用では問題なかったけどこれで思いっきり何かをするというのは意外と使えなさそう. Rails本家からパージされて別プロジェクトとかで管理されているので今後どうなるかわからない(純粋に分離しただけ説もありますが)
全件取るときなどは非常に時間がかかるので,結局mysqlに直繋ぎしたほうが早そうという気持ちもある.
罠
Project.findでIssue(この場合はチケット)で取れるカラムと直接Issue.findで取れるカラムが少し違うことがあって困った.今回はredmine pluginを作って必要なカラムを足すことで回避した.
*1:allってついているのにややこしいな...