Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20171208)最近のRailsフロントエンド事情、国際化gem、mallocでRubyのメモリが倍増、るびま記事募集ほか

こんにちは、hachi8833です。

Railsウォッチ公開前に行われているつっつき会の後、軽呑みになだれこみました。「Service ObjectはパターンじゃないんではGoFデザインパターンほど定義のコンセンサスが取れていないのでデザインパターンの一種のように扱わない方がいいのでは」「名前変えて欲しい」みたいな話が飛び交ったような気がします。

12月のRailsウォッチ2回目、いってみましょう。年の瀬の足音が聞こえる...

Rails: 今週の改修

add_indexでPostgreSQLの演算子クラスをサポート

# activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb#249
       def test_index_with_opclass
         with_example_table do
-          @connection.add_index "ex", "data varchar_pattern_ops"
-          index = @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data_varchar_pattern_ops" }
-          assert_equal "data varchar_pattern_ops", index.columns
+          @connection.add_index "ex", "data", opclass: "varchar_pattern_ops"
+          index = @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data" }
+          assert_equal ["data"], index.columns

-          @connection.remove_index "ex", "data varchar_pattern_ops"
-          assert_not @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data_varchar_pattern_ops" }
+          @connection.remove_index "ex", "data"
+          assert_not @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data" }
         end
       end

つっつきボイス: 「PostgreSQLのoperator classってこれか↓」

演算子クラスにより、その列のインデックスで使用される演算子が特定されます。 例えば、int4型に対するB-treeインデックスには、int4_opsクラスを使用します。 この演算子クラスには、int4型の値用の比較関数が含まれています。 実際には、通常、列のデータ型のデフォルト演算子クラスで十分です。 演算子クラスを持つ主な理由は、いくつかのデータ型では、複数の有意義なインデックスの振舞いがあり得るということです。
https://www.postgresql.jp/document/9.6/html/indexes-opclass.htmlより

「それにしてもこのissue、随分スレが伸びてますね」

PostgreSQLの外部キーをバリデーションなしでも作成できる機能

外部キー追加によるパフォーマンス低下回避のためだそうです。

  • valid: falseオプションを指定すると無効な外部キーを作成できる機能
  • 外部キーバリデーション用のvalidate_foreign_keyメソッドを追加
# activerecord/test/cases/migration/foreign_key_test.rb#230
+        if ActiveRecord::Base.connection.supports_validate_constraints?
+          def test_add_invalid_foreign_key
+            @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", validate: false
+
+            foreign_keys = @connection.foreign_keys("astronauts")
+            assert_equal 1, foreign_keys.size
+
+            fk = foreign_keys.first
+            refute fk.validated?
+          end

つっつきボイス: 「PostgreSQL寄りの改修ほんとうに増えましたね」

preload_link_tagヘルパーを追加

HTTP/2 Early hintsがプロキシでサポートされている場合に対応するそうです。

preload_link_tag("custom_theme.css")
# => <link rel="preload" href="/assets/custom_theme.css" as="style" type="text/css" />

preload_link_tag("/videos/video.webm")
# => <link rel="preload" href="/videos/video.mp4" as="video" type="video/webm" />

preload_link_tag(post_path(format: :json), as: "fetch")
# => <link rel="preload" href="/posts.json" as="fetch" type="application/json" />
...
# actionview/lib/action_view/helpers/asset_tag_helper.rb#260
+        early_hints_link = "<#{href}>; rel=preload; as=#{as_type}"
+        early_hints_link += "; type=#{mime_type}" if mime_type
+        early_hints_link += "; crossorigin=#{crossorigin}" if crossorigin
+        early_hints_link += "; nopush" if nopush
+
+        request.send_early_hints("Link" => early_hints_link) if respond_to?(:request) && request

つっつきボイス: 「PreloadってW3Cの仕様にあるんですね↓: すごく新しい」

Preload: W3C Editor's Draft 30 August 2017

ActiveRecordのスコープ名に予約名を使えないよう修正

# 
+  def test_scopes_name_is_relation_method
+    conflicts = [
+      :records,
+      :to_ary,
+      :to_sql,
+      :explain
+    ]
+
+    conflicts.each do |name|
+      e = assert_raises ArgumentError do
+        Class.new(Post).class_eval { scope name, -> { where(approved: true) } }
+      end
+      assert_match(/You tried to define a scope named \"#{name}\" on the model/, e.message)
+    end
+  end

つっつきボイス: 「Rails開発普通にやっていれば、使ってはいけない名前ってだいたい見当は付きますけどね」「それでもありがたいです」

Rails

Railsの現代的なフロントエンド事情を理解する

TechRacho翻訳記事でお世話になっているEvil Martiansの記事です。Asset PipelineからWebpackに移行した事情などを解説しています。


「Sprocketsの改修(左)が盛り下がる一方、Webpackの改修頻度は高まっている」
同記事より


つっつきボイス: 「これはいいまとめ記事」「PostCSSって初めて知った」「そういえばSassとかCompassってRubyで書かれているけど、そういうのもJSでやりたいってことか: 気持わかる」「Compassって一見便利だけどバッドノウハウの塊ですね」「(Compassに入れ込んだ日々を返してくれ...)」

参考: PostCSS まとめ


postcss.orgより

ニューオリンズRubyカンファレンス動画47本(Ruby Weeklyより)

他にRubyConf 2017を振り返る記事も紹介されていました。


つっつきボイス: 「時間をかけて動画を見る余裕はなかなかないなー」「ところで最近YouTubeの自動字幕の日本語機械翻訳、前より良くなったっぽいですね」「それでも英語の自動字幕の方が精度高いですね: 大文字小文字を区別してたりして驚異」

RailsのモデルidにPostgreSQLのUUIDを使う(Ruby Weeklyより)

短い記事です。新規プロジェクト以外はやめておくほうがよいかもだそうです。


つっつきボイス: 「そりゃもう、IDを後から変えるとか自殺行為w」「ところでID生成については以下の記事↓がとてもよくまとまってますね」

参考: Qiita ID生成大全

RailsでHTTP OPTIONSをうまく扱う方法(Ruby Weeklyより)

# route.rb
  match '*path', {
    controller: 'application',
    action: 'options',
    constraints: { method: 'OPTIONS' },
    via: [:options]
  }

# コントローラ
  class Api::V1::UsersController < ApplicationController
    options do
      {
        schemas: {
          accepts: Company.json_schema,
          returns: Company.json_schema
        },
        meta: { max_per_page: 100 }
      }
    end
  end

つっつきボイス: 「あー、確かにRailsでHTTP OPTIONS扱うの割りと面倒ではある」

参考: MDN HTTP OPTIONS

ActionCableを単独で使ってみた(RubyFlowより)

ActionCableそのものの解説も充実しています。

# 同記事より
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :uuid

    def connect
      self.uuid = SecureRandom.urlsafe_base64
    end
  end
end

つっつきボイス: 「ストリーミングだけやりたいときなんかはRailsなくてもいいのかも: それこそmrubyでやれればよさそう」

Rails 5.2の新機能: HashWithIndifferentAccessfetch_values

とても短い記事です。


つっつきボイス:fetch_values今までなかったのかー」「記事からリンクされている今年4月の#28316の方がわかりやすいですね↓」

# 更新前
hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:a] = 'x'
hash[:b] = 'y'
hash.fetch_values('a', 'b') # => KeyError: key not found: "a"

# 更新後
hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:a] = 'x'
hash[:b] = 'y'
hash.fetch_values('a', 'b') # => ["x", "y"]
hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
hash.fetch_values('a', 'c') # => KeyError: key not found: "c"

asset_sync: RailsとS3の間でアセットを同期するgem

  #config/environments/production.rb
  config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com" # S3の場合
  config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.storage.googleapis.com" # Google Cloud Storageの場合

つっつきボイス: 「これなかなかよさそう: たとえばアセットをS3に置いてRails側でアセットのプリコンパイルをしなくて済むようにすればデプロイも速くなるし」「yarnただでさえ重いし」「★も1600超えてるし使って大丈夫そう」

多言語化gem「Mobility」が0.3にバージョンアップ

Module Builderパターン」のshioyamaさんがメンテしている多言語化gem: Mobilityがバージョンアップされたとのことです。

  • Rails 5.2とSequel 5をサポート
  • ActiveRecordのdirty系メソッド
  • ロケールのフォールバック
  • モデルをdupすると翻訳も複製
  • etc

つっつきボイス: 「gemがメンテされてるのはいいこと」

RubyのModule Builderパターン #1 モジュールはどのように使われてきたか(翻訳)

i18n-tasks: 国際化/多言語化を支援する静的分析gem


github.com/glebm/i18n-tasksより


つっつきボイス: 「このgem今まで知らなかったんですが、前から結構使われてるみたい: 訳ぬけチェックはありがたいです」「さすがに翻訳ミスまではチェックできないだろうけど」「画像に埋まってる文字の翻訳も手に余るでしょうね」

今見ると、Google翻訳で雑に訳を埋める機能までありました。くれぐれもそのまま本番で使わないようご注意ください。

$ i18n-tasks translate-missing
# accepts from and locales options:
$ i18n-tasks translate-missing --from base es fr

activerecord-cause: ActiveRecordのSQL発行タイミングをログ出力するgem

morimorihogeさんが見つけました。

# spec/spec_helper.rb
User.all

# output to log file.
# D, [2015-04-15T22:13:46.928908 #66812] DEBUG -- :   User Load (0.1ms)  SELECT "users".* FROM "users"
# D, [2015-04-15T22:13:46.929038 #66812] DEBUG -- :   User Load (ActiveRecord::Cause)  SELECT "users".* FROM "users" caused by /Users/joker/srcs/activerecord-cause/spec/activerecord/cause_spec.rb:16:in `block (3 levels) in <top (required)>'

つっつきボイス: 「欲しい機能をさっと作る、さすがjoker1007さん」「ビューが重いと思ったら実は背後のSQLが遅いとかざらにあるけど、そういう問題の解明で便利そう」「bulletでカバーしきれないときとか」

Rails: N+1クエリを「バッチング」で解決するBatchLoader gem(翻訳)

Rails Developers Meetup 2017明日12/09開催

錚々たるメンバーが登壇します。キャンセル待ち223人と大盛況です。


techplay.jp

Ruby trunkより

やっぱりwarn_past_scope: trueしたい

3年前にボツになった同様の#10661を引用し、デフォルトオフでいいので変数名の衝突をチェックできるようにしたいという提案です。


つっつきボイス: 「parse.yだ」「parse.y...」「むかーしparse.yを読んでみたことあるけど手強い」「10000行超えてますしね」

Ruby

mallocでマルチスレッドのRubyプログラムのメモリ使用量が倍増することがある

Puma/Unicorn/Passengerの効率を最大化する設定」のNate Berkopecさんの記事です。


つっつきボイス: 「なかなかヘビーかつ濃厚な内容だけどためになりそう」

Rails: Puma/Unicorn/Passengerの効率を最大化する設定(翻訳)

Ruby 3x3の進捗ってどうよ

Ruby 3x3の動きに注目しつつ、昨年提案されたGuildという手法(参考: 「Concurrency in Ruby 3 with Guilds」)による並列化がRuby trunkに見当たらないのを残念に思っているそうです。


olivierlacan.comより

参考: A proposal of new concurrency model for Ruby 3(RubyKaigi 2016資料: PDF)

RubyでDSLを書く

# 同記事より
ConstructionGirl.create_structure(:owner) do
  name { "Michael number: #{Time.now.to_i}" }
  age { [20, 18, 30].sample }
end
# => #<Owner:0x000000040d3258 @name=”Michael number: 1511421963", @age=30>

つっつきボイス: 「オレオレDSL、Rubyistなら一度は通る道ですね」

Embulk: Javaで書かれた一括読み込みツール


embulk.orgより

最初気が付かなかったのですが、Java製です。joker1007さんやmgi166さんなどがRubyでプラグインを書いています。


つっつきボイス: 「↓この図が一目瞭然ですね: Fluentdみたいに常に流し込むのでなく、バッチでアップロード&変換までやってくれるやつです」「うまくはまれば某案件で使ってみようかと思っているところ」


www.embulk.orgより

参考: Fluentdのバッチ版Embulk(エンバルク)のまとめ

るびま執筆者募集


つっつきボイス: 「TechRachoからも記事出してみようか」「Railsネタでもいいのかしら」

そういえば今のるびまは今後Markdownで書けるようになるようです書けるようになったのでした↓。

ダウンロードの多いgemオールタイムトップテン(Ruby Weeklyより)


つっつきボイス: 「このダウンロード数、ほとんどはCIが回しているやつでしょうねー」「人気の指標としては当てにできない感じ」

海外のRubyアドベントカレンダー


つっつきボイス: 「雑にしか探していませんが、こんなに少ないと思わなかった:技術向けアドベントカレンダーはほぼ日本だけのような印象でした」「後は韓国に1つあったぐらい」「もともと西洋のアドベントカレンダーはこういう実物↓ですしね: お菓子やおもちゃ入れたりとか」


businessinsider.comより

BPSアドベントカレンダー2017もどうぞよろしく。

データベース

PostgreSQL: NOT NULL制約を追加して高速化(Postgres Weeklyより)

フランス企業のブログ記事はちょっと珍しい気がしました。


medium.com/doctolib-engineeringより


つっつきボイス: 「NOT NULLしないとたいてい遅くなりますね」

Pgexercise.com: PostgreSQLの出題サイト(Postgres Weeklyより)

追記(2019/07/18): 同サイトの作者より、現在は以下のさらに詳しくなったサイトに移転したとのお知らせをいただきました。ありがとうございます🙇。
* PostgreSQL Tutorial: Learn in 3 Days: https://www.guru99.com/postgresql-tutorial.html



pgexercises.comより


つっつきボイス: 「おー、これいいじゃない! 採用面接で目の前でやってもらうとか」「インターフェイスもいいですね」

一同でとりあえずいくつか解いてみたりしました。

pg_hexedit: PostgreSQLのリレーションファイル向け16進エディタ(Postgres Weeklyより)

wxHexEditorという16進エディタを元にしているようです。

pgeoghegan.blogspot.jpより


つっつきボイス: 「こういうのを持ち出すときは最後の手段ですねw」

check_pgactivity: NagiosのPostgreSQLプラグイン(Postgres Weeklyより)

# OPMDG/check_pgactivityより
check_pgactivity -p 5433 -h slave --service hit_ratio --dbexclude idelone --dbexclude "(?i:sleep)" -w 90% -c 80%

JavaScript

JavaScriptのthisって結局何?

割と短い記事です。詳しくはMDN: thisを見て欲しいとのことでした。

CSS/HTML/フロントエンド

カスタムプロパティ(CSS変数)入門

/* 同記事より */
    --width: 80%
    @media screen and (min-width: 768px) and (max-width: 1020px) {
        --width: 60%;
    }
    @media screen and (min-width: 1020px) {
        --width: 40%
    }

つっつきボイス: 「最初CSS変数という言葉を見ていつの間に?と思ったら、babaさんに『普通カスタムプロパティって言いますね』とツッコまれました」「記事にも書いてありますね」「ただしまだ使うには早い」「IE11で動かないんですね」「それにしても--で書くのかー」「Sassみたいに$にして欲しかった」

Sonarwhal: Webサイトをチェックするサービス(Frontend Focusより)


sonarwhalのマスコットnellieちゃん
24ways.orgより

オンライン版の他にコマンドライン版もあるのが特徴です。


24ways.orgより


つっつきボイス: 「CLIで動くならCIと連携できるということだから、どっかに出力しておくのは悪くない気がする: 全部の項目に対応することもないとは思うけど」

(遠い)未来のCSS(Frontend Focusより)


つっつきボイス: 「Houdiniというタスクフォースをこれで知りました: 仕様書いてる人のスライドだそうです」「Houdiniは結構有名ですね」「それにしてもこのスライド...めくりのアニメーションが見づらい」

参考: CSSのHoudiniとは何者か

Houdiniは明らかにマジシャンのハリー・フーディーニですね。

BootstrapよりCSS Gridの方がレイアウト作成に向いていると思う理由(Frontend Focusより)


hackernoon.comより

その他

Kata Container: コンテナ実装のニューフェイス


katacontainers.ioより

コンテナ間でカーネルを共有しないタイプの実装で、OCI(Open Container Initiative)に準拠しているそうです。


www.opencontainers.orgより

参考: コンテナの軽量さと仮想マシンの堅牢さを兼ね備えた新しいコンテナ実装「Kata Containers」、OpenStack Foundationが発表

deep-image-prior: 相当崩れた画像も復元するニューラルネットワークツール(Python)


つっつきボイス: 「↓このレベルで復元するのか」「しかも学習不要らしいです」「この辺は研究でもホットな分野なので、多分論文読めば何やってるかぐらいはふんわりわかる(アルゴリズムはともかく概要ぐらいは)」

Matzインタビュー

Project-modeからProduct-modeの時代へ


martinfowler.comより

かのMartin Fowler先生のサイトの記事です(筆者は別の人)。ソフトウェア開発をプロジェクトではなくProduct-modeというコンセプトで運営する方法論について解説しています。

QNNcloud: NTTが無料で公開した量子ニューラルネットワーク



qnncloud.comより

まだアカウントを作ってみたところです。

番外

日本語の学習はトップレベルに難しいらしい


www.boredpanda.comより

ヨーロッパ住民にとって。

考えるだけで楽器を演奏

ee_at_9e2_short from Thomas Deuel on Vimeo.


つっつきボイス: 「ヘッドギア付けてるとどうしても患者さんっぽく見える」「演奏していると言えるんだろうか」

年号

シンプル化とは

https://gkojax-text.tumblr.com/post/168287716115

鳥のような恐竜の化石がモンゴルで見つかる

作り物感満載。


今週は以上です。

バックナンバー(2017年度後半)

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Postgres Weekly

postgres_weekly_banner

Frontend Weekly

frontendweekly_banner_captured


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。