| @技術/プログラミング

Pull Request 、レビューしないといけないものが貯まってしまってつらいと感じることが多かった。そういうつらみを解消するための ruboty プラグイン作った。

ruboty-cron と組み合わせて

@ruboty [GitHub の Issue のラベル名]のPull Request

という感じで job 登録しておくと、毎時決まった時間になったら Bot が Pull Request のレビューを促す。

便利。

使い方

  1. ruboty の Gemfile に gem 'ruboty-check_pr_please', github: 'morygonzalez/ruboty-check_pr_please' と追加する
    • 定期的に動かすためには ruboty-cron もいる
  2. ruboty の .env に GITHUB_ACCESS_TOKENGITHUB_REPOSITORY='owner/repo' を書く
  3. ruboty をデプロイする

開発時に苦労した点

ruboty 、 rubory とタイポしてしまうこと多くてつらかった。

| @技術/プログラミング

九州新幹線

関わっているサイトの Rails のバージョンが 3.2.20 から 4.1.8 に上がった。自分は割と傍観していて他の人が主にバージョンアップしてたんだけど、いくつかはまりポイントがあって自分も Pull Request 送ったりしたのでやったことを書いときます。

1. session に注意

Rails 4 から Flash メッセージ(ログインしましたとか)を格納する session のオブジェクトが普通の Hash になってる。 Rails 3 ではこれは FlashHash とかいうやつ。

Rails 3 から Rails 4 へのアップグレードで一旦 Rails 4 を出してやっぱりやめて Rails 3 に戻したりとか、ロードバランサーに Rails 3 と Rails 4 で動くサーバーを混ぜてリクエスト捌いたりするとまずいことになる。

Rails 4 のサーバーで session 出来た人が次にリクエストしたときに Rails 3 に当たるとログイン後とかに session に残っているメッセージを消そうとする処理とかで NoMethodError が発生して落ちてしまう。しかもたちが悪いことに Rack 層で死んでしまったりするから皆さんよく使ってると思われる ExceptionNotification とかで気づくことが出来ない。これはつらい。

対処法としては Hash クラスをオープンしてモンキーパッチするというのがある。こういうの。

↑のだと #alert とか #notice が呼ばれたときにエラーになるので自分は以下のようにした。

# NOTE Rails 4 と Rails 3 を混ぜて使うと Hash#sweep が見つからなくてエラーに
# なるようなのでモンキーパッチします。
# 参照: http://jasonneylon.wordpress.com/2014/08/27/rails-4-flashhash-upgrade-gotcha/

class Hash
  def now
    Rails.logger.warn "Stubbing now during upgrade"
    {}
  end

  def keep
    # stub keep for upgrade purposes
    Rails.logger.warn "Stubbing keep during upgrade"
  end

  def sweep
    # stub sweep for upgrade purposes
    Rails.logger.warn "Stubbing sweep during upgrade"
  end

  def alert
    Rails.logger.warn "Stubbing alert during upgrade"
    self[:alert]
  end

  def notice
    Rails.logger.warn "Stubbing notice during upgrade"
    self[:notice]
  end
end

ただこれもパーフェクトではなくて、何もしないように上書きしているだけなのでログイン後のメッセージとか削除後のメッセージが消せなくなったりする。それでも 500 エラーになるよりかはましなのでどうしても Rails 3 と Rails 4 を混ぜて投入したいみたいときなんかは有効。

2. 絵文字に注意

Rails 3 の頃は ActiveRecord が絵文字を DB に保存することが基本的になかった。ユーザーが POST してきたフォームの中に絵文字が含まれてたら絵文字のところでテキストをぶった切って DB に保存するような挙動だった。しかし Rails 4 からは ActiveRecord は絵文字を素通りさせるようになってしまったので困ったことになる。

絵文字を DB に保存するためには、 MySQL の場合は DB のテキストエンコーディングを utf8mb4 というやつにしてないといけない。ただの utf8 だと保存時に Mysql2::Error: Incorrect string value というエラーが出て DB に保存できない。emojimmy のような gem を使えば utf8mb4 でない DB でも使えるけど、 stores_emoji_characters :column_name を忘れずにモデルに定義しないといけない。たとえば購入時に購入した製品のスナップショットを注文テーブルに取るような DB 設計だと、製品テーブルのカラムは stores_emoji_characters してたとしても注文テーブルのカラムを stores_emoji_characters し忘れていて死亡、というような悲劇が起こり得る。

いまはスマートフォンの時代で、ユーザーが入力してくるフィールドには必ず絵文字が含まれると思っておいた方がいい。スマートフォンをメインで使ってる人たちは開発者が想定しないようなフィールド(名前の敬称とか)に平気で絵文字を使ってくる。下手すりゃ住所や名前にも絵文字を入れて送ってくるかも知れない。アスキー文字しか受け付けないようなフィールドは JavaScript やサーバーサイドでバリデーション行ってると思うけど、マルチバイト文字列を受け付けるフィールドの場合はせいぜい長さくらいしかチェックしてないと思う。チェックを入れて絵文字を弾くことも可能だけど、スマートフォンの時代の流れに反しているしユーザーを失うことになりそう。これから新規でサービスを作ってデータベースに MySQL を使う場合はエンコーディングは utf8mb4 にしておいた方がいい。

他にも script/rails が bin/rails に変わってること忘れてて rails runner なバッチ処理が動いてなかったとか、 paranoia.gem の Rails 4 対応バージョンで物理削除のときに呼び出すメソッド名が変わっててはまったとかいろいろあったけど大きなところは上の session と絵文字だった。開発環境で使ってるときには気がつかず本番に出すまで気がつきにくいという意味で非常にやっかいな現象だと思う。

これから Rails 4 に上げる皆さんは頑張ってください。応援しています。

| @技術/プログラミング

会社のアドベントカレンダーが空いてたので書きました。前日は @kenchan さんでした。


大学生の頃に書いてたウェブ日記を Day One.app に取り込んだ。このウェブ日記は Caldiary というソフトウェアを使っていて、KENT Web で配布されてた CGI をベースにデザインが良くなるように改良されてるやつだった。RSS とかはなく、まだブログがはやる前に作られたものだった。昔ながらの Perl の CGI でデータベースは使っておらず、日記自体はテキストファイルに保存されていた。なので簡単にデータをぶっこ抜けた。テキストエンコーディングが Shift_JIS なのに気をつけつつ UTF-8 に変換して Day One の中にぶっ込んでいった。 Day One が公式で用意してる CLI を Ruby から使いやすくする rb-dayone という gem を使ってやった。

10年前の日記を読み返すといろいろおもしろい。アルバイト先のいやなやつの悪口とかもあるんだけど、人から聞いたおもしろい話を備忘録代わりに書いてて記憶がよみがえったりする。読んでいる本の感想とかもある。黒歴史感あってよい。

Caldiary がすばらしいのはカレンダー形式のサイドメニューがあったことだ(おそらくカレンダー付きの日記だから Caldiry なのだろう)。カレンダー式だと一日もサボれない気がしてほぼ毎日日記を書いてた。 Evernote などパソコン上に日記を書けるソフトはいまいっぱいあるけど、カレンダーが出るのは(自分の狭い観測範囲では) Day One しかない。また Day One は見た目が美しく、過去に書いた文書を読むのに適したインターフェースだと思う。もっと活用していきたい。

むかし日記書いてた人は Day One に取り込んでみるとおもしろいのでオススメです。


この記事はPepabo Advent Calendar 2014 - Qiitaの3日目の記事でした。

明日は未定です。

| @技術/プログラミング

Lokka 、フォームの DOM が bot で解析しやすいのか大量にスパムコメントが登録される。スパムを一括削除する機能は自分で作って Lokka にパッチ送って取り込まれたけど、 Lokka の ORM の DataMapper は一括削除するときに馬鹿っぽい SQL 投げて一括削除は処理が重いし、そもそもスパムコメントを定期的に消すという行為自体が面倒くさい。

むかし P_BLOG でブログ書いてた頃もある頃からスパムコメントが大量に来るようになったので reCAPTHA を導入してみたらとんとスパム来なくなった。

また reCAPTCHA 使おうとして久しぶりに調べてみたら Google のプロジェクトになってた。

設置してから二日くらい経つけどとりあえずスパムコメントは来なくなった。便利。念のためプラグイン化しておいた。

| @技術/プログラミング

Rails の E2E テスト、ずっと Capybara + Poltergeist (PhantomJS)でやろうとしてたけど結局うまくいかなかった。

つらいポイントいろいろあって、 SSL 通信が必要なアクションでリダイレクトが発生してうまく動かないとか、 RSpec の use_transactional_fixtures オプションが利用できなくなるため Database Cleaner とか使う必要あったりとか、Parallel Test するときだけ通らないテストケースあったりとか、高速なマシンを使うときだけ落ちる、 Jenkins でだけ落ちる、といった問題が出てきたりする。

この手の問題、 sleep を入れたりとか mutex 化したりとか場当たり的な対応でテスト通すようにできることはできるけど、 unit テストのようにずーっと通る状態を維持し続けることが難しい(上に書いたように特定の端末でだけ落ちたりする)。おまけに何をやっても RackTest を使う場合に比べてテストが遅くなる。 Pull Request ビルダーでテストが実行し終わるまでに 15 分とかかかったりする。良くない。

かといって JavaScript のテスト書かない訳にはいかない。 JavaScript いっぱい使っててテストがないのはやっぱり不安が大きい。結局、JavaScript のコードを DOM べったりな状態から切り離して、サーバーサイドの Rails アプリケーションの挙動は request spec なり controller spec なりでテストして、 JavaScript のテストは JavaScript で行うのが良いような気がした。どうしてもエンドツーエンドテストやりたかったら Selenium 使うしかない気がする。これはスピードはあきらめて、 Pull Request ビルダーとかでビルドするときはテストやらずに、 master ブランチの定期ビルドとかでぶっ壊れてないか試す、みたいな方法が良いと思う。

もうこれ以上、エクセルにスクリーンショット貼り続ける訳にはいかないんだ。

| @技術/プログラミング

Rails のログファイルを tail -f で見たいんだけど余計なものはフィルタリングして表示されないようにしたかった。最初は以下のようにしてみた。

⚡ tail -f log/development.log | grep -v -e ‘asset|Cache|Rendered’

これだと条件にマッチする行は表示されなくなるけど改行が削除されずに空行がたくさん表示される。これでは見やすいとは言えない。以下のように sed で空行を削除するようにしてみた。

⚡ tail -f log/development.log | grep -v -e ‘asset|Cache|Rendered’ | sed -e ‘/^$/d’

しかしこうすると必要な情報まで表示されなくなってしまう。 tail ではなく cat とかでやると望んだ通りになる。 tail -> grep -> sed の流れだとうまくいかないぽかった。

“tail grep sed” でググったら以下のような記事を発見したので試しに grep に —line-buffered オプションを渡してみた。

⚡ tail -f log/development.log | grep -v -e 'asset|Cache|Rendered' --line-buffered | sed -e '/^$/d'

これで望んだ通りの出力になった。便利。

| @技術/プログラミング

隔週木曜日にグルーヴノーツ社と会場を交代交代で Fukuoka.rb やってたんだけど、8/21 の回がたまたま Fukuoka.go と重なってしまって、Fukuoka.go は同僚でプラチナサーチャーでいけすかない有名な @monochromegane さんが主宰しててペパボ開催だったし、 Fukuoka.rb 重鎮の @nagachika さんが Fukuoka.go に参加登録してたので、どうせならということで Fukuoka.go と Fukuoka.rb 共催することになった。

なんか LT できるっぽい感じだったので大して技術力もないくせに LT させてもらった。他の人のハイレベルな話が続いた後に、本当に Lightening な感じですぐ終わるトークをやらせてもらった。新卒研修のときのスライドの内容をベースに gyowitter のご紹介をさせてもらった。

ただ社外の人も来る勉強会で話できたのは良い経験になった。もうちょっとネタよりから技術的にも意味がある内容の発表をできるようになりたいなぁ。

合同勉強会、普段見かけない人とかも来て良い感じなのでたまにできるといいなぁと思った。あと今回懇親会とか企画されてなかったので次は懇親会もあると良さそう。