RailsでDB Viewを手軽に使う

DB View、使いたいことありますよね。特にRailsから、使いたいことありますよね。ActiveRecordから透過的に使いたいですよね。

とはいえ

RailsにDB Viewを扱うための標準の機能はありません。schema_plusというDB Viewの定義をマイグレーションスクリプト内で書けるような仕組みはありますが、いかんせんちょっとした修正なのにDB Viewの中のSQLを毎回全部書かなきゃいけないのは面倒臭いです。

理想は、

class ApplicantAdoption < ActiveRecord::View
  sql <<-EOS
-- 複雑なSQLが定義してある
  EOS
end

みたいにソースコードの中で直接SQLを書けることですが、そういうGemを書こうとして挫折したので以下のような運用にしています。

普通にSQLファイルを用意する

lib/dbviews以下にDB Viewの定義を含んだ.sqlファイルを用意します。

lib
└── dbviews
    └── applicant_adoptions.sql
CREATE OR REPLACE VIEW applicant_adoptions AS
-- 以下、複雑なSQLが定義してある

そしてこんなRakeタスクを用意します。

namespace :dbview do
  desc 'Reload DB Views'
  task :reload => :environment do
    Dir.glob(Rails.root.join('lib', 'dbviews', '*.sql')).each do |name|
      ActiveRecord::Base.connection.execute(File.read(name))
    end
  end
end

これでrake dbview:reloadを叩くだけでlib/dbviews内のDB Viewを更新する仕組みが得られました。

あとは、

class ApplicantAdoption < ActiveRecord::Base
  # ...
end

と、ActiveRecord::Baseを継承したクラスを作れば、通常のActiveRecordの仕組みからDB Viewを利用することができます。重かったらマテビューこと、マテリアライズド・ビューを使いましょうね。