sqale がサービス終了するので、Heroku に移行した
sqale からの移行推奨先は Heroku
公式にそのような案内がありました。
ただ、正直な話、レイテンシが発生するということ、ドル払いになってしまうことから最初は他のサービスに移行したいと考えていました。
移行先調査した
ということで、移行先を検討してみたんですが、国内サービスは(私の観測範囲では)見当たらなかったんですよね。
で、結局
・AWS
・GCP
・Azure
・Heroku
という形になってしまいました。
この内、
・AWS
はIaaSしかなさそう、
・GCP
はPaaSがあったが、rubyはベータ版?っぽい、
・Azure
はよくわからんかった。
となり、結局Herokuになってしまった。
もう少し調査に時間がかけられたら・移行に時間がかけられたら、というたらればはあるのですが、いかんせんあまり時間ばかりもかけていられなかったので。
Heroku に移行すると大半の人はコストアップになりそう
というのが、Heroku のデータベースに起因してきます。
デフォルトでは、DBの容量がたったの5MB。(ClearDB MySQLの場合)
Sqaleでは2GB使えていた(ハズ)なので、移行を検討している殆どの人が引っか
かるのではないかと。
で、これを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 でバッチ処理を利用する際に知らないとハマるかもしれないポイント!
前提
なににハマったのか?
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 で行われているようなので、これで問題ないはずです。
Rails のルーティングに使用する id を別の内容に変更する方法
通常、edit 等に使用する URI に設定される id を、別のキー等で置き換えたい場合があります。
$ be rake routes Prefix Verb URI Pattern password_resets POST /password_resets(.:format) password_resets#create new_password_reset GET /password_resets/new(.:format) password_resets#new edit_password_reset GET /password_resets/:id/edit(.:format) password_resets#edit password_reset PATCH /password_resets/:id(.:format) password_resets#update PUT /password_resets/:id(.:format) password_resets#update
この id を code に置き換えたい場合、.\config\routes.rb
に以下のようにparam: code
を設定することで、置き換えることができます。
resources :password_resets, param: :employee_code, only: [:new, :create, :edit, :update]
上記のようにすることで、ルーティング情報は以下のようになります。
$ be rake routes Prefix Verb URI Pattern Controller#Action password_resets POST /password_resets(.:format) password_resets#create new_password_reset GET /password_resets/new(.:format) password_resets#new edit_password_reset GET /password_resets/:code/edit(.:format) password_resets#edit password_reset PATCH /password_resets/:code(.:format) password_resets#update PUT /password_resets/:code(.:format) password_resets#update
id とは別のキーを主キーのような形で使う際に重宝します。
Perl でパスワードZipを求められた際の対応方法
前提
Perl は初めて触りました。
対応を求められたサーバの環境は古いです。
$ perl -v This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
QBK (急にボールが来たので)
他にヘルプできそうな人間がいなかったということで、触ったことのない Perl のソースコード修正を求められました。
内容は、Webフォームに添付されたデータをメールで送信するシステムの添付ファイルをパスワードZipで圧縮すること。
Perl 触ったこともないので、極力他に影響を与えたくない一心で対応しました。
調べてみると、Perl の標準モジュールに「Archive::Zip」というものがあるのですが、これはパスワードZipに対応していませんでした。。。
どうしようかなー、と悩んだのですが、Perl からコマンドが呼び出せるらしいので、コマンドでパスワードZipを作成し、それを添付することにしました。
ということで対応したコードが以下。
#----------------------------------------------------------- # パスワードzip生成 # 引数: ファイル名 # 備考: $cf{upldir} には、ファイルの保管場所ディレクトリパスが入っている #----------------------------------------------------------- sub zip { my $ZIP_CMD = "/usr/bin/zip"; my $ZIP_PASSWD = "************"; my ($origin_name) = @_; my $zip_name = "$origin_name.zip"; my $cmd = "$ZIP_CMD -jP $ZIP_PASSWD $cf{upldir}/$zip_name $cf{upldir}/$origin_name"; # パスワードzipの生成コマンド system($cmd); # コマンドの実行 }
で、これをメール送信処理中の添付ファイルをセットする前に
&zip($fname); # $fname には対象となるファイル名が格納されている
と呼び出して、生成したファイルを添付することで対応しました。
今回はパスワード自体をランダム化する必要が無いという要件だったので、ソースコード内にパスワードを埋め込んでいますが、あまりよろしくないという認識はあります。
また、system関数は便利な半面、セキュリティリスクになりそうなので、使い所を見極めて使う必要がありますね。
ActiveRecord に対する scope は条件に一致するレコードが存在しない場合 .all の結果を返却する
scope を利用していたところ、思わぬところでハマってしまいました。。 指定の条件で検索を行い、返却された結果が nil かどうかで条件分岐させようと思っていたのですが、scope を利用すると常に nil ではなく、.all の結果が返却されてきます。
scope :search_with_user, -> (user_id) { where('user_id = ?', user_id) }
よくよく調べて見たところ、 scope はメソッドチェーンを実現するために、nil を返すことはなく、.all を返すんだとか。
要は scope の利用方法に関する認識不足だったのですが、他の人も同じような勘違いをする可能性もあるかも、と思ったのでブログに残しておきます。
Sqaleがサービス終了するとのことです
PaaSとして柔軟に利用していたGMOペパボのサービスであるSqaleですが、終了するとのこと。
【サービス終了のお知らせ】 | Sqale Information
安価であったため、結構使い勝手がよく、ちょこちょこ利用させてもらっていたんですが、rubyのバージョンアップに追従してなかったんで心配していたのですが。。。 代替サービスとしてはHerokuが推奨されています。
Herokuはドル建ての請求になるだろうから、それが経理からいやがられるんだよな。。
iBatis で LIKE 文を使うときの注意点
はじめに…SQLインジェクション発生!
現在対応中の案件で、なぜか iBtais の利用が指定されている案件があるのですが、ここでSQLインジェクションを発生させてしまったので、自戒として記載します。
iBatis の動的パラメータ受け渡し
iBtaisには # と \$ が用意されていますが、# で囲まれたパラメータはエスケープされ、\$ で囲まれたパラメータはそのまま出力されます。
で、LIKE分を記述する際は、%を渡したかったので、
WHERE column1 LIKE $%value%$
と記述していたのですが、そうしたところ、'
などを検索文字として渡した際にエラーが発生しました。
つまり、SQLインジェクションが発生してしまったわけです。
対応策
で、どうしたかというと、
WHERE column1 LIKE CONCAT('%', #value#, '%')
という風に、文字列連結を行うことで対応しました。
一部RDBではCONCAT
に対応していないみたいですが、MySQL、Oracle、MSSQL等は問題なく動作するようです。
PostgreSQLはちょっとだけ微妙。
%
を含んだ検索がうまくいかないようです。
実害はないようですが。