こんにちは、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に移行した事情などを解説しています。
New post: Evil Front Part 1, the first chapter of a three-part beginner-friendly tutorial on building modern front-end in Rails with modular components and Webpacker. Goodbye Asset Pipeline!https://t.co/479OsS8eMH pic.twitter.com/BdxcMOSL8y
— Evil Martians (@evilmartians) December 5, 2017
つっつきボイス: 「これはいいまとめ記事」「PostCSSって初めて知った」「そういえばSassとかCompassってRubyで書かれているけど、そういうのもJSでやりたいってことか: 気持わかる」「Compassって一見便利だけどバッドノウハウの塊ですね」「(Compassに入れ込んだ日々を返してくれ…)」
参考: PostCSS まとめ
ニューオリンズRubyカンファレンス動画47本(Ruby Weeklyより)
他にRubyConf 2017を振り返る記事も紹介されていました。
Good Change, Bad Change: Matz's RubyConf 2017 Keynote – https://t.co/D5B167n8kH (Focused on underlying performance and MRI implementation work.) #video
— Ruby Inside (@RubyInside) December 2, 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の新機能: HashWithIndifferentAccess
のfetch_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
- リポジトリ: AssetSync/asset_sync
Railsのasset_sync gemでAzureBlobが使えなかったのでプルリク作ってみた。
これで私もOSSコントリビューター? どんな反応がくるかな..#rails #azure #blob #asset_pipelinehttps://t.co/2RTodvEaon— TASAKI (@devchick99) December 7, 2017
#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にバージョンアップ
- 元記事: Mobility 0.3: Ready for Prime Time
- リポジトリ: shioyama/mobility
「Module Builderパターン」のshioyamaさんがメンテしている多言語化gem: Mobilityがバージョンアップされたとのことです。
- Rails 5.2とSequel 5をサポート
- ActiveRecordのdirty系メソッド
- ロケールのフォールバック
- モデルを
dup
すると翻訳も複製 - etc
つっつきボイス: 「gemがメンテされてるのはいいこと」
i18n-tasks: 国際化/多言語化を支援する静的分析gem
- リポジトリ: 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
- リポジトリ: joker1007/activerecord-cause
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 Developers Meetup 2017明日12/09開催
錚々たるメンバーが登壇します。キャンセル待ち223人と大盛況です。
Ruby trunkより
やっぱりwarn_past_scope: true
したい
3年前にボツになった同様の#10661を引用し、デフォルトオフでいいので変数名の衝突をチェックできるようにしたいという提案です。
つっつきボイス: 「parse.yだ」「parse.y…」「むかーしparse.yを読んでみたことあるけど手強い」「10000行超えてますしね」
Ruby
malloc
でマルチスレッドのRubyプログラムのメモリ使用量が倍増することがある
「Puma/Unicorn/Passengerの効率を最大化する設定」のNate Berkopecさんの記事です。
New blog post: Malloc Can Double Multithreaded Ruby Program Memory Usage https://t.co/zH1LNN6oo3
Your mileage will vary, but most Puma, Passenger Enterprise and Sidekiq users can reduce memory use by 1.5-4x with a few config/environment changes.
— Nate Berkopec (@nateberkopec) December 4, 2017
つっつきボイス: 「なかなかヘビーかつ濃厚な内容だけどためになりそう」
Ruby 3×3の進捗ってどうよ
Ruby 3×3の動きに注目しつつ、昨年提案されたGuildという手法(参考: 「Concurrency in Ruby 3 with Guilds」)による並列化がRuby trunkに見当たらないのを残念に思っているそうです。
参考: 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で書かれた一括読み込みツール
- 公式: http://www.embulk.org/
- プラグインリスト: http://www.embulk.org/plugins/
- リポジトリ: embulk/embulk
最初気が付かなかったのですが、Java製です。joker1007さんやmgi166さんなどがRubyでプラグインを書いています。
つっつきボイス: 「↓この図が一目瞭然ですね: Fluentdみたいに常に流し込むのでなく、バッチでアップロード&変換までやってくれるやつです」「うまくはまれば某案件で使ってみようかと思っているところ」
参考: Fluentdのバッチ版Embulk(エンバルク)のまとめ
るびま執筆者募集
執筆や編集に興味がある人は https://t.co/Ejw5sIkvxv か @miyohide さんまでどうぞ!
— yhara (Yutaka HARA) (@yhara) December 7, 2017
つっつきボイス: 「TechRachoからも記事出してみようか」「Railsネタでもいいのかしら」
そういえば今のるびまはMarkdownで書けるようになったのでした↓。
ダウンロードの多いgemオールタイムトップテン(Ruby Weeklyより)
つっつきボイス: 「このダウンロード数、ほとんどはCIが回しているやつでしょうねー」「人気の指標としては当てにできない感じ」
海外のRubyアドベントカレンダー
つっつきボイス: 「雑にしか探していませんが、こんなに少ないと思わなかった:技術向けアドベントカレンダーはほぼ日本だけのような印象でした」「後は韓国に1つあったぐらい」「もともと西洋のアドベントカレンダーはこういう実物↓ですしね: お菓子やおもちゃ入れたりとか」
BPSアドベントカレンダー2017もどうぞよろしく。
データベース
PostgreSQL: NOT NULL制約を追加して高速化(Postgres Weeklyより)
フランス企業のブログ記事はちょっと珍しい気がしました。
つっつきボイス: 「NOT NULLしないとたいてい遅くなりますね」
Pgexercise.com: PostgreSQLの出題サイト(Postgres Weeklyより)
つっつきボイス: 「おー、これいいじゃない! 採用面接で目の前でやってもらうとか」「インターフェイスもいいですね」
一同でとりあえずいくつか解いてみたりしました。
pg_hexedit: PostgreSQLのリレーションファイル向け16進エディタ(Postgres Weeklyより)
wxHexEditorという16進エディタを元にしているようです。
pgeoghegan.blogspot.jpより
つっつきボイス: 「こういうのを持ち出すときは最後の手段ですねw」
check_pgactivity: NagiosのPostgreSQLプラグイン(Postgres Weeklyより)
- リポジトリ: OPMDG/check_pgactivity
# 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より)
- 元記事: Lint the Web Forward With Sonarwhal
- サイト: https://sonarwhal.com/
- リポジトリ: sonarwhal/sonarwhal
オンライン版の他にコマンドライン版もあるのが特徴です。
つっつきボイス: 「CLIで動くならCIと連携できるということだから、どっかに出力しておくのは悪くない気がする: 全部の項目に対応することもないとは思うけど」
(遠い)未来のCSS(Frontend Focusより)
つっつきボイス: 「Houdiniというタスクフォースをこれで知りました: 仕様書いてる人のスライドだそうです」「Houdiniは結構有名ですね」「それにしてもこのスライド…めくりのアニメーションが見づらい」
参考: CSSのHoudiniとは何者か
Houdiniは明らかにマジシャンのハリー・フーディーニですね。
BootstrapよりCSS Gridの方がレイアウト作成に向いていると思う理由(Frontend Focusより)
その他
Kata Container: コンテナ実装のニューフェイス
コンテナ間でカーネルを共有しないタイプの実装で、OCI(Open Container Initiative)に準拠しているそうです。
参考: コンテナの軽量さと仮想マシンの堅牢さを兼ね備えた新しいコンテナ実装「Kata Containers」、OpenStack Foundationが発表
deep-image-prior: 相当崩れた画像も復元するニューラルネットワークツール(Python)
そろそろ魔法に見える……。 / “Deep Image Prior” https://t.co/2aeZOR3mHv
— 1007番目のジョーカー (@joker1007) December 4, 2017
つっつきボイス: 「↓このレベルで復元するのか」「しかも学習不要らしいです」「この辺は研究でもホットな分野なので、多分論文読めば何やってるかぐらいはふんわりわかる(アルゴリズムはともかく概要ぐらいは)」
Matzインタビュー
Link: 「『プログラマー35歳限界説』はある」Rubyの父・まつもとゆきひろさんにその真意を聞いた | HRナビ by リクルート: https://t.co/FIEGL0KmLO
— Yukihiro Matsumoto (@yukihiro_matz) December 6, 2017
Project-modeからProduct-modeの時代へ
かのMartin Fowler先生のサイトの記事です(筆者は別の人)。ソフトウェア開発をプロジェクトではなくProduct-modeというコンセプトで運営する方法論について解説しています。
QNNcloud: NTTが無料で公開した量子ニューラルネットワーク
まだアカウントを作ってみたところです。
番外
日本語の学習はトップレベルに難しいらしい
ヨーロッパ住民にとって。
考えるだけで楽器を演奏
ee_at_9e2_short from Thomas Deuel on Vimeo.
つっつきボイス: 「ヘッドギア付けてるとどうしても患者さんっぽく見える」「演奏していると言えるんだろうか」
年号
新元号はもうUnicodeに空きがないからいっその事「㍿ 」にしろよ pic.twitter.com/20uOi4Hh9m
— 知欠健太郎【公式】 (@myuutasu) December 1, 2017
そりゃお前らはエクセルの仕様書に2文字追記するだけだからな。
速報 – 2019年5月1日に新元号、NTTデータや日立は「対応難しくない」:ITpro https://t.co/qzAL6uHJQw
— Miyahan (@miyahancom) December 6, 2017
シンプル化とは
鳥のような恐竜の化石がモンゴルで見つかる
The latest Tips, Tricks, and Something Funny! https://t.co/2ytrKA5IQE #ad #travel
— Paula Robinson (@paulamrobinson) December 8, 2017
作り物感満載。
今週は以上です。
バックナンバー(2017年度後半)
- 20171201 JSON PatchでRails高速化、Knapsack Proでテスト高速化、Decorator/Presenter gem比較ほか
- 20171124 GitHubにセキュリティアラート追加、RailsでVue.jsを使う、Railsテスト本2種、node-pruneで瞬間クリーンアップほか
- 20171117 Rails開発3年分のコツ集大成、PostgreSQL 10.1でセキュリティ問題修正ほか
- 20171110 dry-rbでFormObjectを作る、RailsのSQLインジェクション手法サイト、年に1度だけ起きるバグほか
- 20171020 Rubyが来年で25周年、form objectでサニタイズ、コアなString解説本ほか
- 20171013 Ruby 2.5.0-preview1リリース、RubyGems 2.6.14でセキュリティバグ修正、Bootstrap 4.0がついにBetaほか
- 20171006 PostgreSQL 10ついにリリース、Capybaraコードを実画面から生成するnezumiほか
- 20170929 特集: RubyKaigi 2017セッションを振り返る(2)Ruby 2.3.5リリースほか
- 20170922 特集: RubyKaigi 2017セッションを振り返る(1)、Rails 4.2.10.rc1リリースほか
- 20170915 Ruby 2.4.2リリースで脆弱性修正、strong_migrations gemでマイグレーションチェック、書籍『Mastering PostgreSQL』ほか
- 20170908 Rails 5.1.4と5.0.6リリース、コード書換え支援gem「synvert」、遅いテストを分析するTestProfほか
- 20170818 RailsとYarnでTypeScript、Rails新コミッタにkamipoさんも、CSVにSQLクエリをかけられるツールほか
- 20170804 Rails 5.1.3と5.0.5が正式リリース、GitHubでローカライズ基盤サービス、正規表現で迷路を解くほか
- 20170623 gemを見極める7つのコツ、mixinがよくない理由、重いページをrender_asyncで軽減ほか
- 20170616 railsdiff.orgはアップグレードに便利、RubyのDSLとかっこの省略、TerraformをRubyで制御ほか
- 20170609 ついにtherubyracerからmini_racerへ、注意しないとハマるgem、5.1でのVue.jsとTurbolinksの共存ほか
- 20170602 チームが喜ぶ19のgem、Bundler 1.15が高速化&機能追加、Deviseに挑戦する新認証gem「Rodauth」ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。