こんにちは、hachi8833です。嵐が明けてから早くも汗ダラダラです。
それでは今週のRailsウォッチ、いってみましょう。
Rails 5.1.2rcがリリース: バグ修正が主
今週頭にリリースされたRails 5.0.4に続き、5.1.x系でもバグ修正が行われます。リグレッションがなければ来週月曜(日本では事実上火曜)にリリースされる予定です。
修正点は5.0.4より多めで、ActionCable/ActionMailer/ActiveJob以外はすべてChangelogに修正・追加が記載されています。
差分: 5.1.1-5.1.2rc1
つっつきボイス: 「@kamipoさんの修正、今回も多いなー」「@y_yagiさんのもある」
昨日のRailsウォッチつっつき会では、Webチームの新卒メンバーのyumaさんが初参加してくれました。大画面に移されたRailsリポジトリのコミット数やコミット番号の数字の大きさに驚いていたようです。
Rails: 今週の改修(Rails公式ニュースより)
新機能: mailerでデリバリージョブを細かく設定
# actionmailer/lib/action_mailer/base.rb
helper ActionMailer::MailHelper
+ class_attribute :delivery_job, default: ::ActionMailer::DeliveryJob
class_attribute :default_params, default: {
mime_version: "1.0",
charset: "UTF-8",
つっつきボイス: 「deliver_later
で使うActiveJob継承のActionMailer::DeliveryJob
でカスタムクラスを使えるようにしたということかな」「ジョブのリトライが失敗した場合の対応とか」「メール送信ってまさしくジョブだな、って改めて思う」
パフォーマンス: mass assignmentの速度を改善
# activemodel/lib/active_model/attribute_assignment.rb
+# frozen_string_literal: true
require "active_support/core_ext/hash/keys"
module ActiveModel
def _assign_attribute(k, v)
- if respond_to?("#{k}=")
- public_send("#{k}=", v)
+ setter = :"#{k}="
+ if respond_to?(setter)
+ public_send(setter, v)
else
raise UnknownAttributeError.new(self, k)
end
after 40.172k (± 2.6%) i/s - 203.149k in 5.060347s
before 32.679k (± 4.0%) i/s - 163.929k in 5.025078s
つっつきボイス: 「setter = :"#{k}="
でリテラルをシンボルに変えて高速化してるけど、こういうのをやり始めたらきりがないんではw」「Rails全体でやったら修正量がすごいことになって読みにくそう」「どちらかというとトリビアな部類で、パフォーマンスの改善としてはやや微妙かなー」「レビュアーがString#freeze
をいったん勧めてから『ごめん、式展開ではできないんだった』って取り消してる」「確かにここで#freeze
はできない」「# frozen_string_literal: true
で十分だったのか」
バグ: raw_write_attribute
で主キーにidがマップされていたのを修正
無言で一発mergeされています。
# activerecord/lib/active_record/attribute_methods/write.rb
- write_attribute_with_type_cast(name, value, true)
+ name = self.class.primary_key if name == "id".freeze && self.class.primary_key
+ @attributes.write_from_user(name, value)
+ value
end
def raw_write_attribute(attr_name, value) # :nodoc:
- write_attribute_with_type_cast(attr_name, value, false)
+ name = attr_name.to_s
+ @attributes.write_cast_value(name, value)
+ value
end
つっつきボイス: 「update_columns
でprimary keyの値を設定していると当該オブジェクトじゃなくても更新できてしまったらしい」「privateの#write_attribute_with_type_cast
が削除されてる」「それはたぶんリファクタリングですね」「ロジックを共有する必要がなくなったからって書いてある」
yumaさんが無言でActiveRecord の attribute 更新方法まとめを参考用にSlackに貼ってくれました。助かります。
Railsガイド: Module#delegate_missing_to
これはもう、まんまドキュメントの追加です。
delegate_missing_to
たとえばUser
オブジェクトのmissingを残らずProfile
オブジェクトに委譲したいことがあります。
delegate_missing_to
マクロで以下のように簡単に実装できます。
class User < ApplicationRecord
has_one :profile
delegate_missing_to :profile
end
オブジェクト内で呼び出せるあらゆるもの(インスタンス変数、定数など)が対象になります。
対象のpublicなメソッドのみが委譲されます。
注: 定義場所はactive_support/core_ext/module/delegation.rb
です
シンガポールでRedDotRubyConf 2017が開催
昨日6/22(木)と本日6/23(金)開催されました。
台湾在住のst0012さんとのチャットで知ったのですが、RedDotRubyConfはビジネス的要素とコアな技術トークの両方の要素を含んでいて、非常にバラエティに富んでいるそうです。スケジュールを見ると女性プレゼンターも目立ちますね。
つっつきボイス: 「まさに今日と明日やってるのか」「matsudaさんもいる」「お、Hanamiも発表してる」「ここでもmatzのキーノートで始まりAaron Pattersonが締めくくってる」「2人とも忙しそう」
Passenger 5.1.5リリース: セキュリティ修正と内部強化などが多数
元記事: Passenger 5.1.5: security robustness fix, internal improvements
ダウンタイムの最小化、セキュリティの強化や効率向上など、かなり多数の改善が行われたとのことです。詳しくは今年1月のマイルストーン記事「Passenger 5.1: a new milestone in robustness, security and efficiency」をどうぞ。有料版を購入すればソースにもアクセスできます。
Passengerのつっつきも非常に盛り上がりました。
つっつきボイス: 「Passengerは以前に比べてすごくよくなってる: 特にインストールがとても楽」「嫌いじゃない」「むしろ好き」「ビジネスとしてやってるだけのことはある」「version 2の頃だったかな、有料化して一気にユーザーが離れたのは」「その頃はワーカーがすごくメモリを食ってて、数百回動くと死ぬように作られてたり、それが軽くトラウマだったりはしたけど」「そういえば以前のPassengerは複数バージョンのRubyが共存できない仕様だった」「それ、今は対応済みです」
ワーカーが数百回動くと自ら死んでたとか、昆虫の一生か何かかと思ってしまいました。そういえばworkerってそちら方面の用語では「働きバチ」とか「働きアリ」を指すのでした。
Hackerone: オープンソースのためのセキュリティ情報
この間ウォッチでご紹介したAaron Pattersonインタビューで知りました。Railsのセキュリティチームのメンバーも在籍していて、チームの重要なセキュリティ情報源となっているようです。私も登録しました。
つっつきボイス: 「日本のIPAセキュリティ情報に相当することをやってるのか」「中の人が顔出ししてる」
追記
Hackeroneは賞金システムになっており、脆弱性の報告が受理されると、ソフトウェアの種類に応じて賞金が出ます。Ruby on Railsは賞金額2位で1,500ドルとなっています。
動画: SinatraとGoogleスプレッドシートでランディングページを構築(RubyFlowより)
5分程度なのであっという間です。データベースの代わりにGoogleスプレッドシートでLPを作ってみたい方向け。
render_async
: Railsページの表示が遅い部分をAjaxで遅延読み込み(Ruby Weeklyより)
# ビューヘルパーでrender_asyncをinclude
# app/views/comments/show.html.erb
<%= render_async comment_stats_path %>
# ルーティングを設定
# config/routes.rb
get :comment_stats, :controller => :comments
# コントローラにロジックを書く
# app/controllers/comments_controller.rb
def comment_stats
@stats = Comment.get_stats
render :partial => "comment_stats"
end
# レンダリング用パーシャルを作成
# app/views/comments/_comment_stats.html.erb
<div class="col-md-6">
<%= @stats %>
</div>
つっつきボイス: 「これ、結構いいかも!」「めちゃ重いサイトを遅延読み込みするヘルパーということか」「同じようなもの書いたことある」「コアもシンプル↓」「サーバーサイドレンダリング(SSR)問題についてはさすがに未対応かなー」「render_async
というネーミングってどうでしょう?」「うん、内容にも合ってるしいいと思う」
# https://github.com/renderedtext/render_async/tree/master/lib/render_async
require 'securerandom'
module RenderAsync
module ViewHelper
def render_async(path)
container_name = "render_async_#{SecureRandom.hex(5)}#{Time.now.to_i}"
render "render_async/render_async", :container_name => container_name,
:path => path
end
end
end
日本のRuby事情(Ruby Weeklyより)
先週Twitterで見かけたのですがウォッチに載せそこなってました。
日本のRuby事情、特にコミュニティ関連事情を詳しくレポートしています。ちら見しただけですが、米国はRailsあってのRubyという感じなのが日本だとRubyそのものが根強いとか、日本発の言語ということで政府のバックアップがある点などについて触れ、Ruby World ConferenceやRubyKaigiにも言及して、「Rubyの使われ方が米国とはぜんぜん違うなー」という感じで締めくくっています。
つっつきボイス: 「海外から見た日本のコミュニティ事情面白そう」「日本はいろいろ独特なんだな」「翻訳があったら読みたいなー(チラッチラッ」「読みたいー」
RubyオブジェクトをActive Modelでバリデーション(Ruby Weeklyより)
上の「動画: SinatraとGoogleスプレッドシートでランディングページを構築」の続きという感じです。SinatraでがんばってActive Modelバリデーションしています。
つっつきボイス: 「ActiveModel::Validations
は確かにWebアプリ以外でも便利そう」
Rubyのキューを深掘り(Ruby Weeklyより)
半分以上はC言語です。末尾では、ワーカーを終了させつつ、pop
でブロックされてたらワーカーを起動するという動作を「poisonオブジェクト」を使って実現する方法も紹介されています。
# https://schneems.com/2017/06/14/meditations-on-writing-a-queue/ より
require 'thread'
GLOBAL_QUEUE = Queue.new
POISON = Object.new
threads = 10.times.map do
Thread.new do
loop do
work = GLOBAL_QUEUE.pop
break if work == POISON
puts "Working on #{work}"
end
end
end
20.times do |i|
GLOBAL_QUEUE.push(i)
end
10.times do
GLOBAL_QUEUE.push(POISON)
end
threads.map {|t| t.join }
つっつきボイス: 「キューはキューでもblocking queueの実装の話か」「キューはいろんなところで使われるから読んでおくといいかも」
Dox gemでRSpecからAPIドキュメントを自動生成(Ruby Weeklyより)
markdown形式で生成できるそうです。デモサイトがいくつかあるのでそちらを見るのが早いと思います。
つっつきボイス: 「なかなか表示がリッチでいい感じ」「APIサーバーだけ開発するとき、これも使うとドキュメント作りに便利そう」「その場でSpecを実行できるのか」「ソースも見られる」「以前これと似たようなgemを社内で使おうとした人がいてそちらは全然使い物にならなかったらしいんだけど、なんて名前だったかな」
ブライトンRuby Conference 2017(Ruby Weeklyより)
イギリスでもRuby Conferenceが開かれるんですね。開催は来々週の7月7日です。
つっつきボイス: 「お、クックパッドがGoldスポンサーになってる」
シンボルマークのモスクみたいなのは何だろうと思ったら、ロイヤル・パビリオンのようです。名古屋の金のしゃちほこみたいな定番イメージなんでしょうね。
mixinを避けた方がよい理由(Ruby Weeklyより)
この記事もこの間から見かけていたのですが、ウォッチに載せそびれていました。「mixinは継承を別の文法にしたようなものだ」「継承もだいたいそうだが、特にmixinはコンポジションにしよう」だそうです。
つっつきボイス: 「以前のウォッチでもmixin順序と継承でカオス化する記事を読んだ気がする」「モジュールが増えたときが問題か」
翌日のチェックでもつっついていただいたので追加します。
つっつきボイス2:「mixinだから悪い、モジュール使ってるから悪い、とは思えない」「多重継承は確かにわかりにくいし問題を起こしやすいけど、Rubyの継承の順序はわかりやすい方だと思う」「モジュールがいろんなファイルに分かれていて読みにくいというのは、エディタのタグジャンプとかを使いこなせれば大きな問題にはならないかも」「たぶん重要なのは差分プログラミングを正しく行うことの方なんじゃないかなー」「Railsだったらconcerningを上手に使うとか」「そのためには目の前のコードだけじゃなくて、継承関係も意識するとよいかも(メソッドで言うと#ancestors
)」「z軸というか3次元的に継承の奥行きを捉える視点を持つ感じかな」
Ruby Laser: もうひとつのrubygems.org(Awesome Rubyより)
まだgemの数は少ないですが、検索が速いですね。個人的にはRuby Laserという名前が気に入っています。私の年代だとレーザー光線源にはたいていルビーが使われてたというだけです。今ではシミ取りぐらいにしか使われてないそうですが。
情報源のAwesome Rubyがなかなか優秀なので、ここも今後巡回します。
そこからこの種の情報サイトの浮き沈みについて話題になりました。
つっつきボイス: 「こういう情報サイトってぱっと消えちゃうこと多いよね」「RubyInsideは4年前からまったく更新されてないのにTwitterアカウントだけすごく元気」「それbotじゃなくて?w」
追記(2019/12/06)
rubylaser.orgはその後消えました😇。
Ruby Toolboxの今後について(Ruby Weeklyより)
先週Ruby Toolboxサイトがクラッシュしたのを機に、これまでクローズドだったサイトをオープンソースにしようかどうしようかと問いかけています。
つっつきボイス: 「面白そう、後で読もっと」
Railsのform_with
をform_for
やform_tag
と比較(Ruby Weeklyより)
form_for
の場合:
<!-- m.patrikonrails.com より -->
<%= form_for @user do |form| %>
<%= form.text_field :email %>
<%= check_box_tag :send_welcome_email %>
<% end %>
form_with
の場合:
<!-- m.patrikonrails.com より -->
<%= form_with model: @user, local: true do |form| %>
<%= form.text_field :email %>
<%= form.check_box :send_welcome_email %>
<%= form.submit %>
<% end %>
今後は
form_with
にしよう!振り返るな!
つっつきボイス: 「まform_for
やform_tag
はdeprecatedだしw」「form_with
ではmodel:
を書くべしという感じになってきた」
受け入れテストをアクター/ペルソナで書く(Ruby Weeklyより)
つっつきボイス: 「これもよさそう: 後で読もう」「↑この取り合わせになってしまうことってよくあるけど、本当にちゃんとテストできているんだろうかという気持ちになることが多い」「どこか無理矢理感ある」
- 参考: ペルソナとアクターの違い
使えるgemを見極める7つのコツ(Ruby Weeklyより)
- リポジトリの★とwatchの数
- アクティブなissueとプルリクの数
- 前回のリリース時期
- 依存関係の数
- メンテナーが怖くないこと
- 変更がmergeされてないforkの数
- ドキュメントがあるかどうか
オチは8つめの「そのコードを自分が読んで理解できるかどうか」でした。
つっつきボイス: 「全部同意できる!」「8つ目、別にcrazyじゃないなー」「定番といえばそれまでだけど、まとめ方がうまい」「怖いメンテナーいるいる: 日本人なのに英語で書かないと許さんとか」「怖い人集まってるとこ、あるある」「普通にしてても怖く見えるだけなのかなー、単に顔が怖い人みたいに」「いやいや、もうそういう怖い人たちにとっては怒るのが普通なんですよw」
lemme-pry: pry利用中に依存gemを自動読み込み(Ruby Weeklyより)
- 元記事: Lemme pry!
- リポジトリ: eval/lemme-pry/
珍しくGitLabサイトに置かれているせいか、まだ★がありません。
$ gem install lemme-pry
$ lemme-pry activesupport
...crunching gems...
Using activesupport 5.1.1 (was 4.2.6)
...
[2] pry(main)> 1.second
=> 1 second
パイプも使えるそうです。
$ echo 'time = Time.now' | lemme-pry
...initing stuff...
[2] pry(main)> time
2017-05-25 18:23:40 +0200
バージョン指定とかやりたい場合はGemfile書いてbundlerでやる方がいいかも、だそうです。
つっつきボイス: 「(その場で動かして)うん、動いた」「gemがなくても取ってきてくれるのか」「このgemってどこに入るの?」「やっぱりシステム側に入るみたい」「Gemfileもケアしてくれるといいのに」
Corneal: SinatraでもRailsみたいにgenerateしたい方に(Ruby Weeklyより)
corneal new APP-NAME
とかcorneal scaffold NAME
とかcorneal model NAME
とかできるそうです。起動はshotgun
です。
Sinatraといえばフランク・シナトラなので、Cornealもそういう昔の歌手をもじったのかなと思いましたが違うようです。
つっつきボイス: 「↑この絵がいい」「素直にRails使えばいいんじゃね?」
Rollout: Redisベースでサービスの機能を制御するスイッチ(Ruby Weeklyより)
- リポジトリ: fetlife/rollout
つっついたときは一同あまりピンと来なかったのでさっと流してしまいました。rollout_dashboardなどと組み合わせてサービスの機能をオン・オフ・調整したりするgemのようです。★は2,200を超えています。
Insights: SQL不要の分析ツール(Ruby Weeklyより)
- リポジトリ: mariusandra/insights
デモサイトを見るのが早いですね。
SequelCombine: データセットの結合(PostgreSQL限定)(Ruby Weeklyより)
- リポジトリ: monterail/sequel-combine
DB[:groups].columns
#=> [:id, :name]
DB[:users].columns
#=> [:id, :username, :email, :group_id]
DB[:groups].combine(many: { users: [DB[:users], id: :group_id] }).to_a
#=> [{:id=>1,
# :name=>"Football",
# :users=>
# [{
# :id=> 1,
# :username=> "leonardo",
# :email=> "leonardo@fakemail.com",
# :group_id=> 1,
# },
# {
# :id=> 2,
# :username=> "leonardo2",
# :email=> "leonardo2@fakemail.com",
# :group_id=> 1,
# },
# ]
# }]
つっつきボイス: 「JSONみたいなものの組み立てがやりやすくなるのかな?」「READMEのとおりにやってみたけどうまく動かない...」「こういう感じのものならFacebookが開発したGraphQLの方がよさそうに見える」
ダウンタイムなしでデータベースの巨大なテーブルにインデックスを付ける(RubyFlowより)
短いのですぐ読めます。
def change
add_index :builds, :build_metric_id, :algorithm => :concurrently
end
つっつきボイス: 「要するにPostgreSQLの機能使ってるのか」「PostgreSQLなら驚かない」「最近のPostgreSQLすごいから」「昔MySQLでテーブル複製してインデックスつけてから差し替えたりとか苦労したのを思い出した」
Aquatone: ドメイン名調査ツール(GitHub Trendingより)
- リポジトリ: michenriksen/aquatone
Rubyで書かれたネットワークツールで、Node.jsも使っているようです。
aquatone-discover --domain example.com --sleep 5 --jitter 30
aquatone-scan --domain example.com
つっつきボイス: 「dig
コマンドで足りるんじゃないかな?」「それ系の機能をひととおりぶちこんだ感じ」
Liquid: Shopify作のWebテンプレート言語(GitHub Trendingより)
- 公式: https://shopify.github.io/liquid/
- リポジトリ: Shopify/liquid
Webテンプレート処理用gemです。Shopifyは大手通販サイトですね。
<ul id="products">
{% for product in products %}
<li>
<h2>{{ product.name }}</h2>
Only {{ product.price | price }}
{{ product.description | prettyprint | paragraph }}
</li>
{% endfor %}
</ul>
つっつきボイス: 「これJekyllで使われてるやつだ、ちょうどこの間Jekyll使ったから」
Catphish: フィッシングに使える空きドメイン名をリストアップ(GitHub Trendingより)
- リポジトリ: ring0lab/catphish
悪用厳禁なやつです。マイナーな言語の紛らわしい文字をどんどん追加しているようです。
つっつきボイス: 「面白ーいw」「これ好き」「つかgemですらないのか: catphish.rbが本体」「ac.jpとかeduドメインは普通なかなか詐称できないけど、.
によく似た文字があれば国立大学ドメインっぽいのも取れるなw」「fileformat.infoあたりで探せば見つかるかも」「このPunycodeがあるドメインって、Slackに貼ったときに切り替わって邪魔なんだよなー」「そのせいでSlackに貼れないドメインがあった」
番外: Bootsnap gemがRailsにデフォルトで追加される?
- 元記事: Bootsnapについて(y-yagi)
- PR: #29313 Add bootsnap to default Gemfile
y-yagiさんのブログで知りました。先週の翻訳記事「RailsConf 2017のパフォーマンス関連の話題(1)BootsnapやPumaなど」でも取り上げられていた起動高速化gemのBootsnapがもしかするとRailsに加わるかもしれません。
そういえばこのBootsnapもShopifyのgemでした。
つっつきボイス: 「この手の副作用の少なそうな高速化の仕組みは取り入れられやすいかも」「spring gemを追加したときの意図に似ているかな」「tumblrってブログ書けるんですか?」「え?」「え?」
今週は以上です。
関連記事
- 週刊Railsウォッチ(20170616)railsdiff.orgはアップグレードに便利、RubyのDSLとかっこの省略、TerraformをRubyで制御ほか
- 週刊Railsウォッチ(20170609)ついにtherubyracerからmini_racerへ、注意しないとハマるgem、5.1でのVue.jsとTurbolinksの共存ほか
- 週刊Railsウォッチ(20170602)チームが喜ぶ19のgem、Bundler 1.15が高速化&機能追加、Deviseに挑戦する新認証gem「Rodauth」ほか
- 週刊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など)です。