ダメでしょ!

プログラミングとか怒られた話とか…

Rails の 実行環境を指定するオプション RAILS_ENV をサーバに覚えさせる方法

RAILS_ENV は Rails の実行環境を指定するための環境変数です。
指定しないで実行するとデフォルトとして development で実行されます。

久々に改修依頼が来たWebサイトでは、production 環境と staging 環境を用意していました。
staging 環境でテストを行っている際、RAILS_ENV=staging の指定を忘れて migration させようと試み、development 環境と認識した migration が行われ、エラーとなってしまいました。
よくよく考えると環境変数として RAILS_ENV をサーバに指定しておくべきだな、と思い、追加することにしました。
追加は以下のコマンドで実施できます。

export RAILS_ENV=staging

でも、これだとサーバを再起動したら忘れちゃうので、これを .bash_profile に書き込むことで永続化しました。

# ~/.bash_profile の最後に
export RAILS_ENV=staging

で、保存したら

source ~/.bash_profile

で反映させます。

なんで新規開発の際にやっておかなかったのか。。。


staging 環境を追加する方法はこちらに書いてます。

useless.hatenablog.com

Rails における Staging 環境の追加方法

売り切りで開発したシステムに改修依頼が来た

昔、作るだけ作ったシステムがあったんですが、特に改修とかの話もなく、1年以上経った今になって改修を依頼されました。
ありがたい限りです。

で、改修するんですけど、そもそも改修が来る想定がなかったのでproduction 環境とdevelopment 環境、それに test 環境という Rails そのままで作っていました。
なので、改修する前に staging 環境を用意して、結合テストシステムテストを行うための環境とするようにしました。

Staging 環境を追加するために必要な対応

Gemfile の修正

development 環境でも使っている、以下の gem を導入するために設定を変更しました。

group :development, :staging do
  gem 'bullet'
  gem 'meta_request'
  gem 'rack-dev-mark'
  gem 'rack-mini-profiler'
end

config/environments/staging.rb の追加

config/environments/production.rb をコピーして、config/environments/staging.rb を作ります。

ログレベルの修正、Bullet 及び rack_dev_markの設定追加を行いました。

# ログレベル設定
config.log_level = :debug

# Bullet 設定
config.after_initialize do
  Bullet.enable = true
  Bullet.alert = true
  Bullet.bullet_logger = true
  Bullet.console = true
  Bullet.rails_logger = true
end

# rack_dev_mark 設定
config.rack_dev_mark.enable = true
config.rack_dev_mark.theme = [Rack::DevMark::Theme::GithubForkRibbon.new(position: 'right', fixed: true, color: 'orange')]

config/secrets.yml の修正

ここは環境変数から取得することにして、以下のように追記します。

staging:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

config/database.yml の修正

ここは今回インフラとして heroku を利用するため、特に追加はいらないです。
環境によってはデータベース設定を追記する必要があります。

staging:
  # heroku 上にリリースするため、設定なし

あとは普通に heroku 上に staging 環境を用意し、デプロイすれば staging 環境構築完了です!

思っていたより時間がかかった

あまりよく実施することでもないため、思いのほか調査と過去の記憶を呼び起こすのに時間がかかってしまいました。
こういうのをブログにまとめておくと、あとで読み返して利用できるので、自分のためにもこまめに更新しなきゃいけないですね。

自動化していたつもりの、mac環境構築を2年ぶりに実施したらできなかった

今使っているmacbookproが調子悪くなってきたので、一度きれいにしようと思ってクリーンインストールしたけど、自動化したはずの環境構築がうまくいかなかった。。
今日の夜またチャレンジする予定だけど、ansible の playbook の書き方にどうも変更があったっぽい感じ。
時間をかけたくないから自動化しているのに、自動化がうまく行かなくて時間がかかるって本末転倒な感じが強くて辛い。

ちなみに、昨日チャレンジしていたんだけど、途中から嫌になってネットショッピングとかしてた。
そして Nintendo Switch を勢いで購入してしまった!
楽しみ。

Entity Framework を導入するにあたり、まとまった情報が見つからなくて辛い問題

ようやく Entity Framework を導入することに

今までC#の開発では、所々の事情で iBatis というO/Rマッパーを利用していたのですが、ようやくEntity Framework を導入することで話がまとまってきました。
ということで色々と導入に向けて情報を集めている段階なのですが、導入に際して、まとまった情報がなく、苦労しています。
おすすめの本とか知りたい。。

C# って日本語情報が Web 上に少ないような

感覚的な話なので、それは違うよ! という反応もありそうですが、現在の標準とか、流行りとかが Web 上で感じ取りにくい気がします。観測範囲の問題かもしれません。
もっとどのような構成で開発をしているのかというのがわかるようになるといいなあと思ってます。
まあ、一番は英語をもっと勉強して、直接情報を取得しろよ!ってところなのでしょうけれども。。

Entity Framework 関連で参考にしているサイト

以下にあげさせてもらうサイトとかを確認させてもらいながらなんとか進めています。

Entity Framework カテゴリーの記事一覧 - インクリメンタルなカイハツにっき

C# カテゴリーの記事一覧 - なか日記

今後自分が躓いたところを中心に、ブログに書いていきたいと思います。

今回はただの雑文でした。
しばらく更新していなかったので、なんか更新しなきゃ! となったので。

ActiveAdmin にCSV取込機能を追加する際に便利な gem active_admin_import

前提

ruby 2.1.10p492
Rails 4.2.8
active_admin_import

既存システムの修正依頼

前に他の担当者が作成した Rails アプリで、CSVインポートが上手くいかないという相談があり、アプリを確認したところ、管理サイト側が ActiveAdmin を利用していました。
そして、CSVインポート機能として採用されていたのは active_admin_importable という gem でした。
この gem なんですが、最新バージョンの更新日が2013年4月30日で、約4年更新がありません。
枯れているという意味ではいいのかもしれませんが、既存のソースを確認してみるとモンキーパッチを当てている箇所があったり、Shift-JIS の取込で苦労していそうな感じでした。
なので、別の gem を探してみたところ、今回利用した active_admin_import がいい感じでした。
調査時点での最新バージョンの更新日付は2017年4月26日です。

github.com

機能紹介

使い方はサンプル含め、以下のサイトに記載があります。

Active admin import by Fivell

ざっと機能を確認すると、

  1. 置換(Replacements)
  2. エンコード処理(Encoding handling)
  3. CSVオプション設定(CSV options)
  4. ヘッダー自動付加機能(Ability to prepend CSV headers automatically)
  5. activerecord-import を利用した一括インポート(Bulk import (activerecord-import))
  6. コールバック(Callbacks)
  7. Zipファイル取込(Zip files)

と、なかなか便利な感じです。

使ってみる

gem 'active_admin_import' # ActiveAdmin用CSVインポート機能

上記を Gemfile に記載し、bundle install します。

この gem は active_admin 用ですので、 app/admin/モデル名.rb ファイルに追記していくことになります。

以下は User モデルへの追加例です。

# app/admin/user.rb
ActiveAdmin.register User do
  active_admin_import validate: true, batch_transaction: true, template_object: ActiveAdminImport::Model.new(
    hint: "インポートするCSVファイルにヘッダー行は必要ありません。<br>
    文字コードは CP932(Windows-31J) を想定しています。(Excelを元にしたCSVファイルを想定)<br>
    <br>
    以下の順序で設定されているファイルを取り込みます:<br>
    'ID', 'パスワード', '姓', '名', '所属'<br>
    <br>
    取込に失敗した場合のエラーは5件分のみ表示しています。",
    csv_headers: ['user_id', 'password', 'last_name', 'first_name', 'dept'],
    force_encoding: :'CP932'
  )

上記のように記載するだけで、ヘッダー行なしのエクセルベースで作成したCSVファイルを取り込むことができるようになりました!

使ってみての利点

こちらの gem のいいところですが、

  1. エンコード対応
  2. バリデーション対応
  3. トランザクション対応

です。
日本語を扱う上で エンコードは常に問題になりますし、色々と考える必要に迫られます。しかし、特に英語圏で作成された gem はそのような課題にぶつからないのか、けっこう対応できていない gem は多いように感じます。
また、バリデーションに対応しており、バリデートエラーは画面にメッセージが表示されますので、利用者に優しいです。(active_admin_importable は取込がうまく言ったのかどうかがわかりにくかったんですよね。。)
さらに、トランザクション対応していますので、バリデートエラーが発生した場合はすべての取込をロールバックできます。(バリデートエラーが発生したレコード以外は取り込むように設定することもできます。)

日本語で検索するとactive_admin_importable を紹介しているサイトばかりで active_admin_import を紹介しているサイトがなかったので、今まで選択肢に上がってこなかったかもしれませんが、使ってみることをおすすめします。

sqale がサービス終了するので、Heroku に移行した

sqale からの移行推奨先は Heroku

info.sqale.jp

公式にそのような案内がありました。
ただ、正直な話、レイテンシが発生するということ、ドル払いになってしまうことから最初は他のサービスに移行したいと考えていました。

移行先調査した

ということで、移行先を検討してみたんですが、国内サービスは(私の観測範囲では)見当たらなかったんですよね。
で、結局
AWS
GCP
・Azure
・Heroku
という形になってしまいました。
この内、
AWS
はIaaSしかなさそう、
GCP
はPaaSがあったが、rubyはベータ版?っぽい、
・Azure
はよくわからんかった。
となり、結局Herokuになってしまった。
もう少し調査に時間がかけられたら・移行に時間がかけられたら、というたらればはあるのですが、いかんせんあまり時間ばかりもかけていられなかったので。

Heroku に移行すると大半の人はコストアップになりそう

というのが、Heroku のデータベースに起因してきます。
デフォルトでは、DBの容量がたったの5MB。(ClearDB MySQLの場合)

Sqaleでは2GB使えていた(ハズ)なので、移行を検討している殆どの人が引っか

elements.heroku.com

かるのではないかと。
で、これを1GBにしようとすると、9.99ドル/月が必要になります。

Heroku サーバ自体が、24時間無停止にしようとすると7ドル/月 かかるため、併せて16.99ドル/月 が最低料金になるかと。

Heroku くらいしか同じように使えるところがないからしょうがない・・・

月額が約2倍となってしまい、更に東京リージョンではないためにレイテンシが発生するという全然嬉しくない結果なのですが、他が見当たらないのでしょうがないです。

sqale のサービス終了、痛いです。

移行してみて

で、実際 Heroku に移行してどうなのか、ですが、レイテンシはもちろんありますが、それ以外の部分は結構使いやすいです。
一つつまずいたのが、crontab です。
今までは whenever という gem で crontab の設定を管理していたのですが、Heroku ではcrontab が使えないようです。
代わりに Heroku scheduler というものでバッチ系の処理を管理するみたいです。

Heroku Scheduler | Heroku Dev Center

そのあたりがわかっていなかったので、対応に時間がかかりました。

Rails5 でバッチ処理を利用する際に知らないとハマるかもしれないポイント!

前提

Rails 5.0.2
Ruby 2.4.0

なににハマったのか?

Rails5 で新規アプリを作成していて、バッチ処理を作成しました。
処理は .\lib\tasks\ 配下に格納し、 .\config\application.rb に以下の設定を行いました。

class Application < Rails::Application
  ・・・
  config.autoload_paths += Dir["#{config.root}/lib"]
  ・・・
end

これで lib ディレクトリ配下は自動的に読み込まれる設定になっていると思っていました。
Rails4 時代はこれでよかったんです。。。
さらに、開発環境では問題なくバッチ処理を呼び出すことができます。
これによって問題の解消がますます困難になりました。。。

Rails5 の本番環境では autoload が無効化された

A Guide for Upgrading Ruby on Rails — Ruby on Rails Guides

上記に記載されていますが、Rails5から本番環境では、autoload が無効になっています。
これは、、、知らないと絶対ハマる。

どのように問題に対応するか

上記のURLには解決策として、.\config\application.rb

class Application < Rails::Application
  ・・・
  config.enable_dependency_loading = true
  ・・・
end

と記載することで、autoload するように変更することがあげられています。
しかし、autoload が無効化されたということは、今後使えなくなることが想定されます。
ですので、今回は eager_load を利用することにしました。 .\config\application.rb

class Application < Rails::Application
  ・・・
  config.paths.add 'lib', eager_load: true
  ・・・
end

と指定し、lib ディレクトリ配下を eager_load されるように指定することで問題を解消しました。
app ディレクトリ配下の読み込みはこの eager_load で行われているようなので、これで問題ないはずです。