railsのcontrollerの出力をhtmlファイルとして外部にアップロードする
概要
railsアプリは、ブラウザからのアクセスがあると毎回新しいHTMLを生成しているけど、RSSリーダーのように、常に最新のHTMLを返さなくていいという要件がたまにある。そういうときは、railsを常に起動しておく必要はなくて、定期的にrailsがS3とかにHTMLをアップロードすれば、railsのランニングコストをかなり減らせる。
(例: CloudRunにrailsを立ててスケジューラーで定期アップロードする。 )
本テキストでは、railsが定期的にHTMLをアップロードするための実装について書いてみる。
本文
基本的な方針は、以下の通り
- controllerでHTMLを生成するときは、controller/viewを横断する自作クラスを呼び出す
- アップデートで壊れやすいので不用意にハックをしない
これらをコードにすると以下のようになる。
class MarshmallowsController < ApplicationController
class HTMLRenderer
def initialize
@marshmallows = Marshmallow.order(published_at: :desc)
end
def render
ApplicationController.renderer.render_to_string(
template: 'marshmallows/index',
assigns: { marshmallows: @marshmallows },
format: 'html'
)
end
end
def index
render html: HTMLRenderer.new.render
end
end
ApplicationController.renderer.render_to_stringを使うだけ。
HTMLにアップロードする処理は、controllerで呼び出しているクラスを読んでHTMLに書き出すだけ。
class HtmlDumper
def self.execute!
Rails.logger.info 'Dumping HTML'
html = MarshmallowsController::HTMLRenderer.new.render
Rails.root.join('public/dump.html').tap do |path|
File.open(path, 'w') do |file|
file.write html
end
end
# S3へアップロードする
end
end
まとめ
趣味アプリケーションを低コストで動かすことができるアイディアについて書いた
余談
- HTMLRendererクラスは、リフレクションを使えばもっとシンプルになって、クラスマクロとかで完結できそう
- 過去に上記の仕組みを採用したアンテナサイトを作っていた
-
category:
- ruby