Rails のモデルで次のように列挙型を定義した場合
class Customer < ActiveRecord::Base enum payment_system: { credit_card: 1, bank_transfer: 2 } end
列挙型の値を取り出すときは次のように書く。
Customer.payment_systems[:credit_card] #=> 1
ビューやヘルパーで使うからメモしておく。
Rails のモデルで次のように列挙型を定義した場合
class Customer < ActiveRecord::Base enum payment_system: { credit_card: 1, bank_transfer: 2 } end
列挙型の値を取り出すときは次のように書く。
Customer.payment_systems[:credit_card] #=> 1
ビューやヘルパーで使うからメモしておく。
読了。 Chef Server の章は流し読み。
Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)
技術書は重いし場所をとるので、 既に電子書籍が出ていればそれを買い、 無ければ紙の本を買うようにしたい。 電子書籍の方が紙の本よりも安いことが多いし。
そこで、技術書の電子書籍を購入できるサイトを探してみた。
ヘッダーに表示するサービス名や、フッターに表示するコピーライトを変更しやすいように、 設定ファイルとして YAML で抜き出そうと思っていたけど、 Rails の config に設定を追加できることを今さら知った。
例えば、config/application.rb に
module RailsSample class Application < Rails::Application # ... # タイトルとコピーライトを設定に追加 config.app_name = "サンプルサービス" config.copyright = "tnakamura" end end
と書いておけば、
Rails.application.config.app_name #=> サンプルサービス Rails.application.config.copyright #=> tnakamura
という風に利用できた。 設定を追加したら、Rails アプリの再起動が必要だけど。
環境や開発者に依存する設定は dotenv 使うとして、 そういった環境に依存しない設定は config/application.rb に書けばいいや。
Rails のドキュメントはちゃんと読んでおくべきだったな。
Heroku に 30 秒でレスポンスを返さないといけないルールがあったのを忘れていたので、 急遽 Rails アプリで時間がかかる処理を非同期にすることにした。
Rails で非同期というと Resque や Sidekiq が今のところ人気だけど、 今回は Rails 4.2 で追加予定の ActiveJob を使うことにした。 バックエンドには Sidekiq。
バックエンドに使う Sidekiq は Redis が必要なので、 Vagrant + Chef + Berkshelf で構築している開発環境にインストールする。
Berksfile に
cookbook "redisio"
を追加し
rm -rf cookbooks berks vendor cookbooks
で Cookbook をインストール。
redisio のレシピを使うように Vagrantfile を
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # ... config.vm.provision "chef_solo" do |chef| chef.cookbooks_path = ["./chef/cookbooks", "./chef/site-cookbooks"] # ... # Redis のレシピを追加 chef.add_recipe "redisio::install" chef.add_recipe "redisio::enable" end end
という風に修正したら、vagrant provision
で chef-solo を実行。
ここからは vagrant ssh
で開発環境に入っての作業。
Gemfile に
gem "activejob", "4.2.0.beta1", require: "active_job/railtie" gem "sidekiq" gem "sinatra"
を追加して bundle install
。
ActiveJob は gem を直接使う。
Rails 4.1 のアプリで使いたかったので、activesuport 4.2.0.beta2 が不要な、4.2.0.beta1 を使用。
active_job/railtie
を require しないと、ActiveJob が Rails に読み込まれなかった。
あとは config/environment/development.rb で ActiveJob の設定を記述。 バックエンドで Sidekiq を使うように指定する。
Rails.application.configure do # ... # ActiveJob のバックエンドに Sidekiq を指定 config.active_job.queue_adapter = :sidekiq end
ローカルにインストールした Redis を使うので、Sidekiq の Redis 設定は省略可能。
ちゃんとジョブが実行されたか確認したいので、Sidekiq の Web コンソールをマウントする。 sinatra もインストールしたのは、これが理由。 Sidekiq の Web コンソールは Sinatra を別にインストールしないといけない。
config/routes.rb を次のように修正。
Rails.application.routes.draw do # ... # Sidekiq の Web コンソールをマウント mount Sidekiq::Web => "/sidekiq" end
次のコマンドでジョブを生成。
bundle exec railg generate job calc_score
すると
class CalcScoreJob < ActiveJob::Base def perform(*args) end end
みたいな雛形が app/jobs/calc_score_job.rb に生成されるので、 perform メソッドに非同期で実行したい処理を書く。 こんな感じ。
class CalcScoreJob < ActiveJob::Base def perform(*args) project_id = args[0] project = Project.find(project_id) project.calc_score # 30 秒以上かかる集計処理 end end
コントローラーで作成したジョブを使ってみる。
ドキュメントには perform_later
を使うと書いてあったけど、
RubyGems.org からインストールした 4.2.0.beta1 にはまだ実装されていないので、NoMethodError。
代わりに古い API の enqueue
を呼び出す。
class ProjectsController < ApplicationController # ... def calc_score # 本当は # CalcScoreJob.perform_later(data) # ジョブ実行 CalcScoreJob.enqueue(@project.id) respond_to do |format| format.html { redirect_to @project } end end end
Rails プロジェクト直下に、次の内容を書いた Procfile を作成する。
web: bundle exec unicorn -p $PORT -c config/unicorn.rb worker: bundle exec sidekiq
Foreman を使って Rails サーバーと Sidekiq ワーカーを起動。
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb worker: bundle exec sidekiq
コントローラーのアクションを呼び出してジョブを実行したら、 Sidekiq の Web コンソールで確認してみる。
ブラウザで http://localhost:8080/sidekiq
にアクセスして
Processed の数が増えていれば、ActiveJob のバックエンドとして Sidekiq がちゃんと動いたことになる。
趣味レベルで Heroku にはさわってきたけど、 公式のドキュメントを隅から隅まで読んだわけではないので、 知らない情報を本書から得ることができた。
例えば Herokuのアーキテクチャ、特に Slug。 .slugignore に Slug に含めないファイルを指定して、 Slug コンパイル高速化&サイズ縮小する手法なんかは即試してみた。
本番環境へ移行するときに役立つであろう情報がまとまっているのもありがたい。 SSL の導入手順や、 Heroku Postgres でのデータベースのバックアップ方法と移行方法は、 「なんとなく知ってるけどきちんと調べなきゃいけないな」と思っていただけにタイムリーだった。
欲を言えば、アドオンの解説がもっと欲しいところ。 Logging 系のアドオンは必要って何度も書いてあるから、 Papertrail とか紹介してもよかったと思う。 あと NewRelic はもはや必須アドオンといっても過言じゃないので、 他の説明のついでではなく、ちゃんと専用にページを割いて欲しかった。
最初、買おうかどうか迷っていたけど、 新しい情報を得ることができたし、本番環境へ移行するための方法もゲットできたので、 今では買ってよかったと思っている。
プロフェッショナルのための 実践Heroku入門 プラットフォーム・クラウドを活用したアプリケーション開発と運用 (書籍)
忘れて毎回ネットで検索しているので、ブログにメモしておく。
heroku pg:reset DATABASE
上記コマンドをそのままターミナルにコピペして実行すればいい。DATABASE のところを置き換える必要なし。
ステージング用とプロダクション用に複数のアプリがある場合は
heroku pg:reset DATABASE --app <your_app_name>
を実行する。<your_app_name>
は Heroku アプリの名前で置き換える。