おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

ginza.rb 第33回で Rails 5 の新機能について学んだ

3/15は ginza.rb の33回目のミートアップでした。

Ginza.rb 第33回 もうすぐやってくる!Rails 5を見ておこう - Ginza.rb | Doorkeeper

前回のミートアップ時に、きっと Rails 5.0 がリリースされているだろうと思い Rails 5.0 をテーマとして設定しましたが、見事に期待が外れましたね><

未完成のリリースノートを読みつつ、主にメジャーな機能について内容を確認していきました。ざっとメモ書きを載せます。何か間違っている点などありましたら教えていただけると嬉しいです!

Ruby on Rails 5.0 Release Notes — Ruby on Rails Guides

ActionCable

  • ご存知 websocket 用
  • pubsubサーバとして postgres と redis に対応している
  • Basecamp のチャットサーバとして使われているので、一応実績がある
    • しかしどれくらいのサーバ台数でどのくらいのクライアント数をさばいているのだろう。気になる
  • puma, unicorn, passenger などのサーバで使える
  • 内部で thread 使っているので、仮に unicorn を使っていても ActionCable を使うのであれば thread safe なコードが求められる

Rails API

Rails::API について発表した - おもしろwebサービス開発日記

Active Record Attributes API

Rails 5のActive Record attributes APIについて | 日々雑記

Test Runner

Rails 標準の test ツールが便利になりました

  • 結果に色がつく
  • ファイル、行を指定して実行、fail-fast や defer-output など、RSpec の便利機能の取り込み

Exclusive use of rails CLI over Rake

  • これまで rails で何か実行する時は、rails コマンドもしくは rake コマンドでしたが、rails に統一されました
  • rails db:migrate みたいな
  • 実態は rake コマンドを叩いているだけ
  • rake も引き続き使える

Sprockets 3

  • リリースノートには 3 って書いてあるけど多分 4
  • source map
    • development で assets 結合しないと、ファイル数が多い時に遅いけど、結合するとエラー時にどこがエラーなのかわかりにくいのを解消
    • 結合しても、エラー時にどこがエラーなのかわかる
  • es6 サポート
    • babel が依存関係に入った
  • manifest.js
    • これまで、最終的にコンパイルされるファイルは Rails の config で指定していたけれど、それを js 上で指定できるようになった
    • ちょっと疎になった

Turbolinks 5

Ruby 2.2.2+ required

読んで字のごとく。Ruby 2.2.2 以降に対応

Notable Change

時間が余ったので、細かい変更も見ていました。以下気になった変更点

  • bin/rails restart コマンドが追加された
    • 実態は tmp/restart.txt を更新しているだけ
    • puma 2 系は tmp/restart.txt に対応してなかった(はず)だけど、3.0 で対応された
  • bin/rails initializers コマンドが追加された
    • initializer を読み込む順番で表示してくれる
    • べんりでは
  • bin/rails dev:cache コマンドが追加された
    • development 環境で cache のオンオフができる
    • 実態は tmp/caching-dev.txt を作ったり消したりしてるだけ
    • caching-dev.txt の有無で cache の設定を上書きしている
  • bin/update スクリプトが追加された
    • bin/setup の update 版
    • セットアップと同様、アップデートもコマンド一発でできるようにするのが Rails Way ってことなのかな
  • http_cache_forever というのが controller 用のメソッドとして追加された
    • 読んで字のごとく
  • config.force_ssl にオプションが追加
    • 一回 force_ssl な設定が追加されてしまったブラウザを、リセットするのが楽になった
    • HSTS Preload 用の設定も入った

以上

まだまだ読めていない変更点があるので、次回は続きを読んでいく予定です。

iosアプリ開発時に実機とローカルサーバを通信させるための快適な設定方法について

iOS アプリ開発をしている時に、web上のサーバではなく、ローカルマシンのサーバと通信させたくなる状況はよくあるかと思います。僕はまず次のようなコードを書いて、さらにコンパイラ用のフラグに -D DEBUG と設定することで対応しました。

#if DEBUG
   let host = "http://localhost:3000/"
#else
   let host = "https://production.example.com/"
#endif

この Qiita の記事を参考にさせていただきました。

Swift での #ifdef DEBUG のやり方 - Qiita

これで大丈夫!…ではありません。ローカルサーバは http なので、ATS(App Transport Security) を許可する設定を追加しないと通信できません。

[iOS 9] iOS 9 で追加された App Transport Security の概要 | Developers.IO

単純に Info.plist に localhost:3000 を例外として許可する設定を追加して、しばらくは平穏に過ごせたのですが、実機で検証しようとした時に問題点に気づきました。そうです。実機からローカルマシンのサーバに接続する時には localhost ではダメなのでした。

それでは localhost をやめて、例えば willnet.local のような、mac に設定してある hostname を利用すればどうでしょうか。問題なく動きそうですね。ただ、これでは複数人数でiOS開発しようとした時に、各自のローカルマシンに立てたサーバと接続したくなるケースに対応できません。適宜ホスト名を書き換えてビルドし、コミットする時にはホスト名の変更を含めないように気をつける…そんな開発プロセスになりそうです。なるべくなら避けたいですね。

そこで次の二つのブログエントリを参考にしました。

上記のブログでやっていることを簡単にまとめると、Build Phases の Run Script 内に、Info.plist を書き換えるスクリプトを書きビルド時に実行することで、ビルドしたマシンの hostname を動的に Info.plist に設定しています。

これでURLを書き換えることなく快適に開発ができるようになりました。やりましたね。

しかしこれをiOSプロジェクトごとに毎回やるのは面倒ですね。Run Script を自動で追加できるライブラリのような仕組み*1があればそれを作りたいのですが、そのあたり詳しいかたいたら教えてください><

*1:そもそもそんなことできるんですかね…

Rails::API について発表した

FiNC さんの社内マイクロサービス勉強会と、表参道.rb にて、そろそろリリースされそうな Rails 5 におけるメジャーフィーチャの一つ Rails::API について話しました。

雑感

スライド読むと分かるように、Rails::API は API サーバを作る時の銀の弾丸でもなんでもなくて、条件に合致したときに使うとちょっとだけ速くなりますよ、軽くなりますよという機能なのでした。

Rails::API の機能面としてはそれだけなのだけど、Rails は Rack Middleware や ActionController::Base 内の Module が疎になっていて、着脱が簡単なんですよというのを示す良い例にもなっていると思います。使っていない Middleware や Module を外すことで、手軽にちょっぴり速く/軽くできるので、API サーバに限らず不要なものがある場合は外してみてしまっても良さそう。ただし本当にちょっぴりしか変わらないので、速度を劇的に改善する必要のある場合は別の言語を検討するのが良いのではないでしょうか。

他の言語との比較も時間あったらやりたい*1ですね。

*1:そういうの知りたい会社さんがお仕事依頼してくれたら嬉しいなあ

DroidKaigi2016に参加した

DroidKaigi 2016 に行ってきました。

おそらくブログには書いていなかったのですが、1年ほど前に RubyMotion で Android アプリを開発したことがあります*1。それ以来、あまり Android 開発トレンドのキャッチアップができていなかったので、ここらで遅れを取り戻そうとしたのでした。

個人的には、最近どのようなライブラリが使われているのか、RxJava、テストが気になっていたのでそれらの発表を中心に見て回りました。

Rx系については具体的に何が嬉しいのかよくわかっていなかったのですが、非同期処理をうまく扱えるイメージがついたので今後積極的に使っていきたいです。

テストに関しては Jenkins を使っているところが多いようで、Ruby 界隈とは異なる印象。おそらく(減ってきたとはいえ)機種依存での不具合を発見するために実機を通してテストをせざるをえないのが、一般の CI サービスを使う場合の壁になっているのかなと感じました。

全体通じて、スタッフの方々がとても頑張ってくれていて過ごしやすいKaigiでした。また来年も参加する予定です。

*1:RubyMotion ネタで去年の DroidKaigi に CFP を出したのですがあえなく落選しました><

権限管理のgemで良いのはどれ?

昨日は ginza.rb 31回目のミートアップでした。

Ginza.rb 第31回 ユーザの権限管理どうしてます? - Ginza.rb | Doorkeeper

@kyuden_ さんに、現状の二大認可 gem である cancancan や pundit、それらの問題点を解決するために作った banken について発表してもらいました。

感想

個人的には pundit のリソースベースでの権限管理は悪くないと思っています。ただスライドで書かれているような、Admin::UsersControlller と UsersController で処理を分けたい時などのエッジケースで回避策を模索しなきゃいけないのはだるいですね。banken だと、コントローラベースなのでコード記述量は増えてしまうのですがその分ハマりどころが減るので、そのトレードオフを考慮しつつ案件によって使い分けるのがいいのかなという気持ちです。

rails-assets の調子が悪い時の回避策

皆さん、rails-assets は使っていますか?

rails-assets は、Gemfile で js や css のライブラリを指定して、バージョン管理や依存の解決などをしてくれるとても便利なサービスです。

しかし最近ではその役目を終えたとして、最大で今年末でサポートを終了するとしています。

Future of rails-assets · Issue #291 · rails-assets/rails-assets

そしてもう閉じることが決まったプロジェクトだからなのか、あまり活発にメンテナンスをしていないような印象を受けます。昨年からrails-assets を運営しているサーバが不安定になることが多く、rails-assets に依存しているプロジェクトを持つ会社さんは、bundle update やデプロイに失敗して辛い日々を過ごしたのではないでしょうか。

そんな折、明日 2016/1/19 にサーバのSSL証明書の期限が切れることがわかりました。証明書の期限延長対応がされるまで、困ったことになりますね…><

f:id:willnet:20160118191355p:plain

(追記) 証明書は lets'encrypt を利用しており、(おそらく)自動で更新されるようになっているようです。よかったですね。 SSL certificate for rails-assets.org will expire soon · Issue #306 · rails-assets/rails-assets

僕がお手伝いしているクリニカルプラットフォームさんでも rails-assets を利用しており、昨年 rails-assets が不安定になった際に、非常用として回避策を用意しておきました。

その回避策をシェアしておきますので、僕たち同様に困っている方がいらっしゃったらご利用下さい。以下は クリニカルプラットフォームさんの esa@masa_iwasaki がまとめてくれた記事を改変したものです。

rails-assets.org が不安定な場合

rails-assets.org へ接続ができない場合、 bundle install が終了せず最悪デプロイができない状況に陥ります。

急いでいる場合は、rails-assetsのリポジトリからソースコードを手に入れ、開発環境でgemパッケージをビルドし、外部に公開してそのURLをGemfileで参照するという手段があります。ただし、多少の時間はかかりますので、時間に余裕を持って取り組むのがベストです。

rails-assetsでgem生成

rails-assetsREADMEに従ってセットアップします。redis さえ動いていれば、最後の foreman start は必要ありません。

git clone git@github.com:rails-assets/rails-assets.git && cd rails-assets
bundle install && npm install
cp config/database{.sample,}.yml
cp config/application{.sample,}.yml
# edit config/database.yml and config/application.yml if necessary.
bin/rake db:setup
foreman start

手元でgemを以下のようにビルドします。各assetのバージョンは各プロジェクトのGemfile.lockを参照して取得してください。

bundle exec rake 'component:convert[jquery, 2.1.4]'
bundle exec rake 'component:convert[jquery-ui, 1.11.4]'

↑の作業を楽にするために、Gemfile.lock をパースして、実行すべき rake タスクを出力する簡単なスクリプトを書きましたのでご利用下さい。parse_gemfile_lock.rb のように保存して ruby parse_gemfile_lock.rb Gemfile.lock で実行できます。

files = ARGF.readlines.grep /rails-assets-/
files.map(&:strip!)
files.reject! { |file| file[-1] == '!' || file.match(/[>=<]/) }
files.each do |file|
  name, version = file.split(' ')
  name.gsub!(/rails-assets-/, '')
  version.gsub!(/[\(\)]/, '')
  puts "bundle exec rake 'component:convert[#{name}, #{version}]'"
end

外部への公開

rails-assetsのワーキングコピー直下にあるpublicディレクトリ以下をrsync等を使って外部に公開します(public以下のファイルさえあれば、gem serverとして機能します)。公開先はどこでもいいですが、最も簡単なのはAWS S3を利用することでしょう。

gem sourceの変更

プロジェクトのルートディレクトリに移動し、Gemfile 中の https://rails-assets.orghttp://公開URL に変更して、bundle install を走らせれば終了です。

ローカル環境で確認したい場合

localにgemがすでにインストールされている場合、公開URLのものは当然インストールしてくれません。もし、ちゃんとインストールが出来ることをローカル環境で確認したい場合は、インストール済みのrails-assets-*系gemを削除してください。ざっくりと全部抜くのであれば、以下のようなコマンドで削除できます。

$ gem list --no-version | grep rails-assets- | xargs gem uninstall

最後に

役に立った!と思ったら下記エントリの応援や応募などをお願いします (\( ⁰⊖⁰)/)

犬の手も借りたい!ヘルスケアITのスタートアップがRubyエンジニア募集! - クリニカル・プラットフォーム株式会社の求人 - Wantedly

合わせて読みたい

最近のお仕事について - おもしろwebサービス開発日記

Lotus についての雑感

今回の ginza.rb ミートアップで、Lotus と呼ばれる、Ruby製フレームワークについて学びました。

ginzarb.doorkeeper.jp

@y_yagi さんが概要を資料にまとめてくれたので、それに沿って特徴や機能について理解を深めつつ、気になることについてワイワイ話しました。

感想

Lotus は、Rails とは異なる明確なポリシーで設計されており好感が持てます。Rails は少人数、短期間で素早くサービスを作るのに向いているフレームワークだと思いますが、最近はある程度大規模な開発にも使われているはずです。その時に開発メンバーの習熟度にばらつきがあると、例えばコントローラに不必要なインスタンス変数が定義されたり、ActiveRecord を継承したモデルにビジネスロジックが書かれすぎてモデルが肥大化したりします。こうしたことは少しなら問題ないのですが、開発が進むにつれ徐々にビジネスロジックの実装を難しくし、バグが入り込みやすくなり、さらにコードを読み書きする楽しさを奪っていきます。Lotus は、そのようなことが(比較的)起こりにくい設計になっています。

機能的に足りていない部分(関連やi18n)があるので、どんどん使いましょう!とは言えないのですが、Rails で消耗した人向けのもう一つの選択肢になればいいなあ。