- 開発
週刊Railsウォッチ(20170602)チームが喜ぶ19のgem、Bundler 1.15が高速化&機能追加、Deviseに挑戦する新認証gem「Rodauth」ほか
こんにちは、hachi8833です。週刊Railsウォッチ末尾の「関連記事」がだいぶ多くなったので今回から昨年分を削りました。すっかり夏日ですね。
Rails: 今週の改修(Rails公式ニュースより)
新機能: スレッド独立な属性シングルトンActiveSupport::CurrentAttributes
DHHがactivesupport/lib/active_support/current_attributes.rbをまるまる書き下ろしています。
たとえば「現在のユーザー」をコントローラでもモデルでもルーティングでもビューでも同じように取れるようにした、と理解しました。グローバル変数のような凶悪なものではないにしても、このシングルトンはかなりそれに近い位置づけのようです。DHHも「使いすぎに注意」と警告しています。
ChangeLogより:
主なユースケースは、リクエストごとの属性を全部まとめてシステムのどこでも読み書き可能にすること。
コードが長いので引用しづらいですが、結合テストから短めのものを見つけました。
## https://github.com/rails/rails/blob/156a506875889748f382ddd2946e480fe5389a29/railties/test/application/current_attributes_integration_test.rb#L12
class Current < ActiveSupport::CurrentAttributes
attribute :customer
resets { Time.zone = "UTC" }
def customer=(customer)
super
Time.zone = customer.try(:time_zone)
end
end
後はCurrent.customer.なんちゃら
で読んだり書いたりする、という感じでしょうか。
つっつきボイス: 「DHH、毎度のことながら大胆だなー」「『嫌なら使うな』ってことなんでしょうね」「railtieのto_run
とto_complete
はそれぞれ実行前、実行後なのか」
ついでながら、以前から疑問だったことをつっつきの場で聞いてみました。「Railsのrailtieって何でこういう名前なんでしょうか?railsのutilityだから?」
「railtieって、『仲間』『つなげる』みたいなニュアンスですかね。Rails::Railtie を継承したクラスではRails起動時の処理を書けるようになったり、Rails::Engineの場合は /app の下がアプリとほぼ同等の扱いになったりするんです。」
おー、「rail」と「tie(結びつける)」の合成ということなのでしょうか。今までcookieみたいな語尾かと思っていました(違ってたらすみません)。railtiesと複数形になっていることが多いですね。
そして先ほど画像でググってみてやっと納得できました。線路と枕木をつなぎとめるものを指すんですね。「レイルティー」じゃなくて「レイル・タイ」と。
参考: Gem、Railtieプラグイン、Engine(full/mountable)の違いとそれぞれの基礎情報
新機能: cookieとセッションの暗号化
cookieの暗号化方式を段階的にAEAD(認証付き暗号)のAES-256-GCMに移行するそうです。暗号化方式が古いcookieをコンバートするコードまで入っています。
@encrypted ||=
if upgrade_legacy_signed_cookies?
UpgradeLegacyEncryptedCookieJar.new(self)
+ elsif upgrade_legacy_hmac_aes_cbc_cookies?
+ UpgradeLegacyHmacAesCbcCookieJar.new(self)
else
EncryptedCookieJar.new(self)
end
ガイドも更新されました。
移行の理由: GCMなら認証と暗号化が一括処理できるし、SHA1衝突問題の対応も始めておきたい。AEADは一般にシンプルでエラーが起きにくいし。
つっつきボイス: 「古いcookieまで面倒見るのかー」
修正: secrets:edit
でsecrets:setup
も実行
rails secrets:setup
してなくてもrails secrets:edit
を実行できるようになりました。
# https://github.com/rails/rails/pull/29195/files#diff-39e92f58049d45463507199343fe3ba1L39
- unless File.exist?("config/secrets.yml.enc")
+ unless (defined?(@@skip_secrets_file) && @@skip_secrets_file) || File.exist?("config/secrets.yml.enc")
なお、rails secrets:setup
すると以下が追加されます。
# config/environments/production.rb
config.read_encrypted_secrets = true
つっつきボイス: 「これでちょっと親切になったかも」「今まではsetupしないとeditできなかったのか」
そこからRailsの標準プリローダーであるspringの話に発展しました。
つっつきボイス:
「こういう親切がありなら、rails db:migrate
のときとかに自動でspring stop
してくれてもいいのにー。忘れた頃にマイグレーション邪魔される」
「spring邪魔、意義わからんw」
「spring stop
じゃぬるい、私なんかspring kill
してますよ」
「気になる人は↓こうしてみてはどう?」
DISABLE_SPRING=1 rails db:migrate
( ・∀・)イイ!!こと教わった。
修正: 数値バリデーターのリグレッションエラーを修正
# https://github.com/rails/rails/commit/d83b8e65102d625c9024cd9a2727a10b0ef83b79#diff-58f66170fe2bce77e8a8b3c69b77a0d6L39
- unless raw_value.is_a?(Numeric)
+ if raw_value.is_a?(Numeric)
+ value = raw_value
+ else
value = parse_raw_value_as_a_number(raw_value)
end
つっつきボイス:
「ところで、こういう『過去に修正したエラーの再発』を何て呼んでます?」
「先祖返り」
「デグレ」
「リグレッションとかリグレスって、日本じゃ言わないかなー」
改良: ActiveRecord初期化の最適化を改善
ActiveModelの初期化は、実はRails 4.2からRails 5にアップデートしたときにかなり遅くなってしまっていたのだそうです。今回の改修では、STIで倍以上、非STIで1.3倍の高速化を達成しています。
================ Instantiate STI base class without attributes =================
v5.1.1 patched: 20641.2 i/s v5.1.1: 9916.0 i/s - 2.08x slower
================= Instantiate Non-STI class without attributes =================
v5.1.1 patched: 27071.0 i/s v5.1.1: 20723.3 i/s - 1.31x slower
つっつきボイス: 「STIってうまくはまるとすごくコードがコンパクトになるんですよ」「使いどころが思いつかないなー」「STI、気をつけないと危なっかしそうですね」
参考
Bundler 1.15がリリース、高速化を果たす(Ruby Weeklyより)
起動時の読み込みが高速化されたそうです。Ruby/Rails開発者が最も頻繁に使うgemだけに助かります。gem install bundler
でアップグレードできます。
また、以下の新しいコマンドを追加し、manページもがっつり改訂したそうです。
bundle info
bundle issue
bundle add
bundle pristine
Bundler 1.15については別記事でお伝えいたします。
inflector.me: Railsのinflection(活用形)を確認できるWebサイト
- サイト: http://inflector.me/
- リポジトリ: cannikin/inflect_check
個人的にありがたいかも。まだ★1個だったので押しときました。
当初入力がサニタイズされていなかったらしく、<>
などを含む文字列を入力すると無残に崩れることをakioさんが発見しましたが、私がissueを送ったらすぐ直してくれました。
なお、#ordinal
と#ordinalize
は序数(1stとか2ndなど)の接尾語のメソッドなので、レシーバーがIntegerのときのみ有効です。
Ruby 2.5で導入されるKernel#yield_self
(Ruby Weeklyより)
Object#tap
と似ているが戻り値は異なるそうです。
# https://bogdanvlviv.github.io/posts/ruby/new-method-kernel-yield_self-since-ruby-2_5_0.html より
User = Struct.new(:name, :sex) do
def male?
sex == "male"
end
end
user = User.new("Bogdan", "male")
user.yield_self { |u| u.male? ? "Mr. #{u.name}" : "Ms. #{u.name}" }
# => "Mr. Bogdan"
user.yield_self { |u| "Hi, #{u.name.upcase!}" }
# => "Hi, BOGDAN"
user.name
# => "BOGDAN"
つっつきボイス: 「instance_evalと何が違うんだろう?」「名前が重要ってことなのかなぁ」
関係ありませんが、Rubyでは#next
の反対は#pred
なんですよね。理由は知りませんが、#prev
じゃないのが以前からとても気になってます。
補足
Railsウォッチをまとめていて、ちょうどこんなissueを見つけました
「#instance_eval
あるから#yield_self
いらねーじゃん」
「いや、同じじゃないし↓」
42.instance_eval { abs2 } #=> 1764 (Kernel#yield_selfでは動かん)
42.yield_self #=> #<Enumerator: 42:yield_self> (BasicObject#instance_evalとかでは動かん)
RubyモジュールとBuilderパターン(Ruby Weeklyより)
かなり長いですが、モジュールとBuilderパターンに絞り込んでいるので読みやすいと思います。
チームが喜ぶ19のgem(RubyWeeklyより)
TechRachoで取り上げていないものはないかと思って探すと、こんなのがありました。
VCR
VCRは、テスト中のブラウザ画面の遷移を記録・再生するgemです。テストのたびに保存しておけば重要な証拠になりますね。非常に人気が高いらしく、JavaScriptを中心にいろんな言語に移植されています。gemspecを見た限りではseleniumを使っていませんね。
なお、英語圏では昔のカセット式のビデオデッキのことをVCR(video cassette recorderの略)と呼ぶのが普通です。
wicked_PDF
wicked_PDFは、コントローラに以下のように書くとビューテンプレートのHTMLをPDFに変換してくれます。
# https://github.com/mileszs/wicked_pdfより
class ThingsController < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render pdf: "file_name" # Excluding ".pdf" extension.
end
end
end
end
つっつきボイス: 「wicked_pdf、イイデスヨーイイデスヨー」
参考: Railsでwicked_pdfを使って画像入りのPDFを生成する
retryable
retryableは、応答の遅いのろまな外部レガシーAPIがテストの足を引っ張らないよう、応答なしで例外が発生したときにリトライしてくれます。RubyWeelkyの別エントリにあるsemianというgemもretryableと似た感じですが、こちらは本番運用向けでしょうか。
つっつきボイス:
「リトライ処理って結構面倒なんですよね」
「そうそう、インターバルをだんだん伸ばしていって、ある程度のところで諦めるとか、そのへんをちゃんと作りはじめると、メインの処理より豪勢になってたりして」
「メインの処理なんてたった1行なのに、だんだん何がしたかったのかわかんなくなってくる」
「これからはこの gem 使わせてもらいましょう!」
AWS Tokyo Summitに参加していたmorimorihogeさんも、
「指数backoffタイマ的なものを今さら実装するのはめんどいすね(固定値ならいいけど引数で色々制御したりとか考えると車輪の再発明感ある)」
参考: 指数backoffタイマ
roadie
roadieはHTMLメールをRubyらしく書けるgemです。HTMLを少しでも書かずに済ませたい方に。
# https://github.com/Mange/roadieより
document = Roadie::Document.new "<html><body></body></html>"
document.add_css "body { color: green; }"
document.transform
# => "<html><body style=\"color:green;\"></body></html>"
つっつきボイス: 「roadie、よさそう!」
groupdate
groupdateは、ActiveRecordモデルで年/月/週/日/時/分/秒などさまざまな単位のグループ化を支援します。MySQL/PostgreSQL/RedShiftでハッシュと配列の両方をサポートしています。ActiveSupportの手が届いてないさまざまな時間の区切りを使いたいときによさそうです。
# https://github.com/ankane/groupdate より
User.group_by_week(:created_at, time_zone: "Pacific Time (US & Canada)").count
# {
# Sun, 06 Mar 2016 => 70,
# Sun, 13 Mar 2016 => 54,
# Sun, 20 Mar 2016 => 80
# }
Groupdate.week_start = :mon # 週頭は月曜
Groupdate.day_start = 2 # 一日の区切りは朝2時
つっつきボイス: 「groupdateを知ってたらもっと楽できた気がする」
apartment
apartmentは、Railsアプリを間貸しする機能を提供します。テナントごとにデータを隔離しつつ、共通の機能も与えられるそうです。リソース管理の一種という感じですが、間貸しに特化しているところがよさそうですね。テナントごとにRailsアプリのインスタンスを立ち上げたくない/立ち上げられない事情がある場合などに使えそうです。
つっつきボイス: 「apartment、小規模案件なら使えることがあるかも」「めぞん一刻思い出した」「あれって間仕切り破綻してますからw」
Red Arrow: Apache ArrowのRubyバインディングgem(RubyWeeklyより)
- リポジトリ: red-data-tools/red-arrow
Apache Arrowはカラム指向のインメモリデータ処理システムです。
公式サイトで目についた箇条書きだけひとまずメモします。
- 全システムが同じメモりフォーマットを利用する
- システム間通信のオーバーヘッドがない
- プロジェクト間で機能を共有できる(Parquet-to-Arrow readerなど)
DiscourseのRailsはRuby 2.4.0でどれだけ速くなったか(RubyWeeklyより)
DiscourseはRailsで書かれたSNSアプリです。Besides GC, Has Ruby 2.3 Helped Rails Performance?も同じ著者の関連記事です。
Railsの認証システムをセキュアにする4つの方法
TechRachoの翻訳記事「そのパッチをRailsに当てるべきかを考える」や「Ruby on Rails のhas_many 関連付けのフィルタテクニック4種」のducktypelabs.comさんの新着記事です。
認証関連のセキュリティに関心のある方向け。
Rodauth: 認証システムのニューフェイス
Railsで認証といえばすっかりDeviseですが、上のductypelabsの記事ではDevise以外にRodauthについての言及が多かったので、気になって少しだけ追ってみました。
Rack対応アプリならRailsに限らず広く使えるようです。Why Rodauth?には「DeviseやAuthlogicやSorceryと違ってRailsに限定されない」とあります。
Rodauthのドキュメントの中心はREADME_rdoc.htmlで、それ以外はAPIドキュメントレベルのようです。OmniAuth連携はまだやってないようで、むしろOmniAuthのライバル扱いされてたりします。
Deviseのように手順を集めたWikiはまだ見当たりませんでしたが、GoogleグループのフォーラムやIRCがあり、筋もよさそうなのでREADMEとAPIでやれるかもしれません。もちろん使ってみないことにはわかりませんが。
まだ★300個台ですが、後発らしく気合が入っています。GitHubのIssueも全部つぶされています。
豊富な実績と引き換えに煮込みすぎたカレーのようになってしまったDeviseを果たして追い上げられるかどうか。気になる方は以下のスライドをどうぞ。
Rubygems.orgがElasticsearchを採用して高速化(RubyWeeklyより)
We rolled out new search for https://t.co/9Prknbum8M last week. It's a lot faster! pic.twitter.com/52I7W9jV6w
— David Radcliffe (@dwradcliffe) 2017年4月26日
どっかで見たなと思ったら、昨年のRailsウォッチでもrubygems.orgがCDNで倍速になった↓ことを報じたときと構図がまんま同じでした。間違い探しみたいですね。
We have cut the https://t.co/9PrknbLX0k response times around the world in half, thanks to @fastly! pic.twitter.com/ccInMmdDIx
— David Radcliffe (@dwradcliffe) 2016年10月12日
Railsのアップグレード代行します(RubyWeeklyより)
宣伝なのですが思わず目を留めてしまいました。Railsのアップグレードに特化した請負サービスですね。「寝ている間にやっときます」だそうです。
別に張り合うわけではありませんが、もちろんBPSでもRailsアップグレードのご相談をお受けしておりますので、お気軽にお問い合わせフォームにてお尋ねください。
Webpacker 3題
Rails 5.1のWebpackerに関連する記事です。
Webpackerが2.0にアップグレード(RubyWeeklyより)
- リポジトリ: rails/webpacker
Elmサポート追加とバグ修正です。ElmはいわゆるAltJSのひとつで、コンパイルするとHTML/CSS/JSまで生成するうえ、関数型言語なんだそうです。
参考: Elmというミニマムでフレームワークにもなる関数型altJS言語を触ってみよう!!!
WebpackerからWebpacker-liteが分離した理由(RubyFlowより)
React on Railsというgemのメンテナが、RailsとWebpackerのポリシーと合わなかったらしく、forkしたそうです。
React on RailsはWebpackerのほんの一部の機能しか使わないのに、Railsで公式採用されたWebpackerはAsset Pipelineなど多くの機能を統合しているのでWebpackerに手を入れるのにRailsコミッターとやりとりしなければならず、つらかったようです。
ReactをRailsで使う(RubyFlowより)
React on Railsの導入手順記事を参考までに。
PostgreSQLの優れた資料「篠田の虎の巻」
PostgreSQL 10の新機能を追っていて見つけました。日本ヒューレット・パッカードの日本語技術ブログですが、ここからダウンロードできる「篠田の虎の巻」は日本語版と英語版があります。
新機能や検証結果がよくまとまっていて、とても参考になります。
今年2月更新のPostgreSQL 9.6向けの「篠田の虎の巻」が現行の9.x系では最新の資料のようです。こちらも大力作です。
RailsでPostgreSQLのJSONカラムを使う(RubyWeeklyより)
つっつきボイス: 「MySQLでもJSONカラムできますよ、一応」「知らなかった!」
Rubyに恋してしまう理由
Quoraの記事ですが、身も蓋もなくて思わず吹き出してしまいました。Why do people fall in love with Python?なんてのもあります。
Whyで始まる質問は、よほど具体的な問いでないと無意味なものになりやすい傾向がある気がします。どんなふうに回答しようと、「ではそれはなぜ?」といくらでも無限後退できてしまうので。無限後退を止めるには神を持ち出すぐらいしか思いつきません。
さらに、好き嫌いは理屈では決定されないことが脳科学周りでだんだん明らかになってきています。好き嫌いは出会いの瞬間に脳の原始的な層で決まり、その後は大脳皮質が全力でその好き嫌いを正当化するんだそうです。
動きの遅い生物が動きの速い餌を捕まえる動画
赤玉が足の速いエサ、青玉が足の遅い捕食者です。閲覧にはFlashプレイヤーが必要です。
番外: エントロピック重力理論の解説
昨年末のRailsウォッチで報じた「エントロピック重力理論」の当事者へのインタビューを含む解説記事です。ちびちび読んでますが、宇宙全体を熱力学的に捉えて一般相対論の重力方程式に変換するみたいな部分に勝手に興奮しています。
熱力学はこれ以上ないくらい地味で目立たなくて婦女子にモテない学問と思われているっぽいですが、アインシュタインはニュートン力学やマクスウェル電磁気学より熱力学を信頼していたそうです。
今週は以上です。
関連記事(2017年分)
- 週刊Railsウォッチ(20170526)増えすぎたマイグレーションを圧縮するsquasher gem、書籍「Complete Guide to Rails Performance」ほか
- 週刊Railsウォッチ(20170519)Rails 5.1.1/5.0.3リリース、RailsでAPIサーバーを作る、HackerNewsでトップになるチャンス?ほか
- 週刊Railsウォッチ(20170512)Rubyの不思議な挙動「シャドウイング」、コードレビュー作法を定めるDanger gemほか
- 週刊Railsウォッチ(20170428)Rails 6.xでの’#form_for’と
#form_tag
廃止決定のその後、deviseの5.1対応はこれから、ほか - 週刊Railsウォッチ(20170421)RailsConfが来週アリゾナで開催、コントローラを宣言的に書けるdecent_exposure gemほか
- 週刊Railsウォッチ(20170414)サーバーを危うくする1行のコード、PostgreSQL 10の新機能ほか
- 週刊Railsウォッチ(20170407)N+1問題解決のトレードオフ、Capybaraのテスト効率を上げる5つのコツほか
- 週刊Railsウォッチ(20170331)PostgreSQLの制約機能を使えるRein gemはビューも使えるほか
- 週刊Railsウォッチ(20170324)Ruby 2.4.1リリース、GAEがついにRubyに対応、このgemがないと生きていけない27選ほか
- 週刊Railsウォッチ(20170317)Railsパフォーマンスチューニング本、DBレコード存在チェックの最速メソッド、RubyのUnicode正規化ほか
- 週刊Railsウォッチ(20170310)クールなDocker監視ツールCtop、RailsがGoogle Summer of Code 2017に正式参加、Unicode 10.0.0ドラフト発表ほか
- 週刊Railsウォッチ(20170303)5.0.2正式リリース、メタプログラミングに懲りた話、bundler 1.12のバグ、すぐ試せるWebアノテーションほか
- 週刊Railsウォッチ(20170227)Rails 4.2.8リリース、SHA-1コリジョンアタック、便利なハッシュ変換ツールほか
- 週刊Railsウォッチ(20170217)Rails 4.2.8.rc2リリース、Ruby 2.4正規表現とActiveSupportのnormalizeほか
- 週刊Railsウォッチ(20170210)JRubyやRubiniusの配列への追加はスレッドセーフではないほか
- 週刊Railsウォッチ(20170203)AnyLogin gemで開発中に楽々再ログイン、イベント数ベース課金の監視サービスRollbarほか
- 週刊Railsウォッチ(20170127)わかりやすいAWSサービス名、Rails DBは便利、TruffleRubyの驚異的速度ほか
- 週刊Railsウォッチ(20170120)Ruby 2.5.0 devリリース、古いMySQLのサポート終了、uniqメソッドが削除ほか
- 週刊Railsウォッチ(20170116)Ruby 2.4の詳細、範囲指定したsumメソッドは速い、rescueの挙動を動的に変更ほか
- 週刊Railsウォッチ(20170110)ReactをRailsに置き換える、Ruby 2.4の新機能ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。