- 開発
週刊Railsウォッチ(20170630)Rails 5.1.2/4.2.9リリース、高機能なRailsキャッシュcounter_culture、Vue.jsの公式SSRガイドほか
こんにちは、hachi8833です。最近RubyWeeklyより先にウォッチで紹介している記事がちょくちょくあることに気づきました。
6月最後のRailsウォッチ、いってみましょう。
Rails 5.1.2と4.2.9が正式リリース(Rails公式ニュースより)
5.1.2の修正は、これまでにもRailsウォッチで取り上げてきたものが多いので何だか親しみが持てます。ActionMailer、ActiveJob、ActionCable以外で修正が行われています。
4.2.9は重大なセキュリティ関連の修正のみとなっています。Changelogに追記されているのはActiveSupport、ActiveRecord、ActionPackのみです。
Rails: 今週の改修(Rails公式ニュースより)
パフォーマンス改善: fixtureの挿入にバルクINSERT
を使用
# https://github.com/rails/rails/pull/29504/files#diff-694eb08d69d73b367d06242dd0aba454R354
+ table = Arel::Table.new(table_name)
+ manager = Arel::InsertManager.new
+ manager.into(table)
+ columns.each_key { |column| manager.columns << table[column] }
+ manager.values = manager.create_values_list(values)
+ execute manager.to_sql, "Fixtures Insert"
つっつきボイス:
「このArel::InsertManager
を使ってbulk insertできるのか」「こんなのあったとは」
「自分だったらこういう場合activerecord-import使うかなー、バリデーションもできるし: ただRailsのcoreにこれを入れたくないのはわかる」
そこからデータベースへのバルクインポートの話題になりました。
つっつきボイス:
「速度出したいときは生SQL書くことになる」「SQL力を試されますね」
「1日1000万レコードぐらいのデータをTSV(タブ区切りテキスト)作ってCOPY FROM
でインポートしたり」
「やった中ではMySQLのLOAD DATA INFILE
が速かった」
修正: #current_page?
ヘルパーがRailsエンジンのルートパスを正しく処理しないことがあった
パスの末尾の/
の有無で比較に失敗することがあったのが修正されました。
# https://github.com/rails/rails/pull/29503/files#diff-26e33d6e883deb07332ac9c1922eadc0L555
- url_string.chomp!("/") if url_string.start_with?("/") && url_string != "/"
+ if url_string.start_with?("/") && url_string != "/"
+ url_string.chomp!("/")
+ request_uri.chomp!("/")
+ end
リレーションのmerge
でINNER JOIN
を維持するよう修正
修正前のAuthor.joins(:posts).merge(Post.joins(:comments))
の結果
- 期待:
SELECT ... INNER JOIN posts ON... INNER JOIN comments ON....
- 実際:
SELECT ... INNER JOIN posts ON... LEFT OUTER JOIN comments ON...
morimorihogeさんが「これ挙動が変わる可能性あるからArel使いは注意した方がいいかも」と指摘しました。
# https://github.com/rails/rails/pull/27063/files#diff-06059df8d3dee3101718fb2c01151ad0L107
- def join_constraints(outer_joins, join_type)
+ def join_constraints(joins_to_add, join_type)
joins = join_root.children.flat_map { |child|
make_join_constraints(join_root, child, join_type)
}
- joins.concat outer_joins.flat_map { |oj|
+ joins.concat joins_to_add.flat_map { |oj|
if join_root.match? oj.join_root
walk join_root, oj.join_root
else
oj.join_root.children.flat_map { |child|
- make_outer_joins oj.join_root, child
+ make_join_constraints(oj.join_root, child, join_type)
}
end
}
pixeltrix先生も「ぼくmerge
使ったことないけどね: 自分ならクエリビルダーメソッド使う」「誰かにとってはバグでも別の人には機能だったりすることだってあるから注意したい」
元の挙動が仕様かどうか誰もわからなかったので、テストが頼りということのようです。
つっつきボイス: 「JOIN
かー」「JOIN
を使うメソッドをどこまで信用できるかという気持ちはある」「Arelで複雑なクエリ書きたくないですね」
最近のRuby trunkから
いずれも卜部さんが立てた無言のissueです。
/000000000000000000000000000000000000000000000000000000000000000000000
begin raise ensure return end; self
/#{break}/o
つっつきボイス: つっつきボイス: 「#13687、これどういう構文だろ」「正規表現の端?」「割り算?」
$ ruby -ve '/000000000000000000000000000000000000000000000000000000000000000000000'
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]
-e:1: unterminated regexp meets end of file
-e:1: warning: possibly useless use of a literal in void context
「正規表現か!」「でも落ちないな」「開発版での現象だって」「よく見たら2.5devって書いてあった」
オンライン書籍: Demystifying Rails(Ruby Weeklyより)
- サイト: Demystifying Rails
無料で全ページ読めます。demystifyはmystifyの反対語で「神秘のベールを剥がす」のような感じです。
つっつきボイス: 「ほむほむ、No Magic Railsとか割りといいかも」「Railsの背後の挙動がわからなくて怖いとか、背後の挙動がわかるまで使いたくない!みたいな人とかにいいのかな: PHPやってた頃は自分もその傾向がちょっとあった気がする」「少なくともRailsガイドを見て書いたレベルではなさそうですね」
そこから、数年前BPSの勉強会で取り上げた「Crafting Rails 4 Applications」という書籍の話題になりました。
つっつきボイス: 「あの本はものすごい深掘りしているところはいいんだけど、網羅性が足りない点が残念」 「そういう意味ではDemystifying Railsは役に立つかも」
SQLとビジネスロジック
SQL、ORM、アプリケーションコード、ビジネスロジックの関係について論じています。
ブログ主のDimitri Fontaine氏はオープンソース、特にPostgreSQL界隈では著名なエンジニアで、PostgreSQLの機能と便利技トップ10のCraig Kerstiensも一目置いているようです。
つっつきボイス: 「SQLって本来ビジネスロジックやトランザクションなどをすべて記述できる能力があるから、ORMやアプリケーションコードとどう共存するかというのは一度は考える話だなー」「ストアドプロシージャは使いたくない」「特に名を秘すけど、ORMなど絶対認めん!みたいな過激な主張をたまに見かけますね」「それネットのどこにありますか?」「それはね...」
メタプログラミングの隠れたコスト(RubyFlowより)
「速度」「読みやすさ」「検索性」の3つを挙げています。Rubyのstatic analysisについても言及しています。
以下のコードはcreate_post_tags
以外のドキュメントが生成されません。
# http://www.blackbytes.info/2017/06/costs-of-metaprogramming/ より
class RubyBlog
def create_post_tags
types = ['computer_science', 'tools', 'advanced_ruby']
types.each do |type|
define_singleton_method(type + "_tag") { puts "This post is about #{type}" }
end
end
end
rb = RubyBlog.new
rb.create_post_tags
rb.computer_science_tag
以下のようにしてyardドキュメントを生成する手もありますがいつも使えるとは限らず、結局grep
頼みになってしまったりします。
class Thing
# @method build_report
define_method(:build_report)
end
つっつきボイス: 「メタプロに速度を求めちゃいけないw」「検索性の低さは確かにある: IDEでインデックス化できないし」
複雑な正規表現をシンプルなパーサーで置き換える(RubyFlowより)
こんな感じに変換してくれるパーサーを書いてみたそうです。
/
( # Capture group is so split will include matching and non-matching strings
(?: # The first character of the key, which is
(?!\s)[^:\s"'\[]{1} # ..any valid "key" char not preceeded by whitespace
|^[^:\s"'\[]{0,1} # ..or any valid "key" char at beginning of line
)
[^:\s"'\[]* # The rest of the "key" chars
: # a colon
(?: # The "value" chars, which are
'[^']+' # ..anything surrounded by single quotes
| "[^"]+" # ..or anything surrounded by double quotes
| \[\S+\sTO\s\S+\] # ..or anything like [x TO y]
| [^\s"'\[]+ # ..or any string not containing whitespace or special chars
)
)
/xi
つっつきボイス: 「Parser書きたくなる気持わかる: 神正規表現使われるとレビュー意欲そがれるw」「キャプチャグループとか名前付きグループみたいなのって最近知った」「コメントのない神正規表現はマジ勘弁」「正規表現書くのは好きだけど確かに人のは読みたくないw」
「何でしたっけ、(?=)
とか(?!)
みたいなのっていつも覚えられなくてこんなスニペット作りました↓」
"foobar".match(/foo(?=bar)/) # => #<MatchData "foo"> # 直後に bar がある foo
"fooxxx".match(/foo(?!bar)/) # => #<MatchData "foo"> # 直後に bar がない foo
"foobar".match(/(?<=foo)bar/) # => #<MatchData "bar"> # 直前に foo がある bar
"xxxbar".match(/(?<!foo)bar/) # => #<MatchData "bar"> # 直前に foo がない bar
「私もオレオレアプリの管理画面にlook aheadとlook behindのカンペ付けてます↓」
⭐Vue.js公式のサーバーサイドレンダリング(SSR)ガイド⭐
当初Build your first server-side rendered React app with Railsにしようかと思ったのですが、最近公開されたらしいVue.jsの公式SSRガイドを見つけたのでこっちにしちゃいました。
これ、すごくありがたいと思います。
- はじめに
- 基本的な利用法
- ユニバーサルなコードの書き方
- ソースコードの構造
- ルーティングとコード分割
- データのプリフェッチとステート
- クライアントサイドのhydration
- Bundle Rendererの導入
- ビルドの設定
- CSSの管理
<head>
の管理- キャッシュ
- ストリーム
- APIリファレンス
hydrationはVue.jsの用語のようです。化学用語だと「水和物」ですね。
今週の⭐を進呈いたします。おめでとうございます。
ActionMailerとSidekiqでメールを非同期送信
Making a Rails App Move Faster: A Tale of Lessons Learnedで紹介されていました。
手順が具体的なのですぐ使えそうです。
つっつきボイス: 「mail.deliver_later
だなやっぱり↓」
user = User.find(1)
mail = UsersMailer.welcome_email(user.id)
#mail.deliver_now
mail.deliver_later
Anyway Config: さまざまなソースから設定を読み込めるgem(Ruby Weeklyより)
- リポジトリ: palkan/anyway_config
今のところ★50個超えです。
つっつきボイス: 「なまじいろんな書き方ができると、コード全体でconfig parameterへのアクセス方法がバラバラになって後でつらくなりそう」「設定をいろんなところから読み込めると便利なのはわかるけど」
ChromeでヘッドレスなCapybara feature specを動かす(Ruby Weeklyより)
capybara-webkitとChromeDriverでヘッドレスにテストする解説記事です。
このサイトでは他にORMを使ってないRailsでFactoryGirlを使うコツなども面白そうです。Rails以外にiOSやAndroid記事もたくさんあるようです。
counter_culture: Railsアプリのカウンタキャッシュ(Awesome Rubyより)
- 元記事: counter_culture: Turbo-charged counter caches for your Rails app.
- リポジトリ: magnusvk/counter_culture
ActiveRecordでさまざまなカウンタキャッシュオプションが使えるようになるgemです。
# magnusvk/counter_culture より抜粋
counter_culture :category, touch: true
counter_culture :category, column_name: 'product_weight_ounces', delta_column: 'weight_ounces'
counter_culture :category, foreign_key_values:
proc {|category_id| [category_id, Category.find_by_id(category_id).try(:parent_category).try(:id)] }
つっつきボイス: 「お、これいいかも!」「Rails標準のcounter_cache
って機能が超シンプルなんで、ちょっと凝ったことしようとするとすぐ物足りなくなる」「使ってみよう」「READMEにコード例もちゃんと書いてあるのはうれしい」
Rubyのこの辺もうちょい何とかなあれ11選(Awesome Rubyより)
タイトルだけ見て使いこなし系記事かと思いきや、毛色が少し違う感じです。走り書きっぽくてちょっと読みづらい...
p Integer("0123")
で8進数出力するとか勘弁。今どきパーミッションぐらいでしか使わないような8進数はp 0o123
使え。- Hashにもっとメソッド欲しい。
Hash#zip
がイマイチ。Enumerable#count_by
が欲しい。- URIやnet/httpが古い
- pryを標準ライブラリに加えて欲しい。
Pathname#glob
も使いにくい。system "wget", "-w", wait_time.to_s, uri.to_s
みたいにパラメータを#to_s
しないといけないの勘弁。- シリアライズはいっそ素性のいいRuby Object Notation(RON)にしようよみんな: yamlとかJSONとかじゃなくて: JSON5も完全じゃないし。
irb(main):006:0> a = {x: 1, y: 2}
=> {:x=>1, :y=>2}
irb(main):007:0> b = {y: 3, z: 4}
=> {:y=>3, :z=>4}
irb(main):008:0> a.zip(b)
=> [[[:x, 1], [:y, 3]], [[:y, 2], [:z, 4]]]
irb(main):009:0> (a.keys|b.keys).map{|k| [k, [a[k], b[k]]]}.to_h
=> {:x=>[1, nil], :y=>[2, 3], :z=>[nil, 4]}
同じサイトの別記事「The Next Ruby」はもっと言いたい放題で「end
やめてPythonみたくインデント表記になあれ」「モジュールのネスト、滅せよ」という感じです。
私もこういうこと考えがちなのでいい年して頬を赤らめてしまいました。
つっつきボイス: 「p Integer("0123")
はちょっと気をつけたいかなと思ったけどRubyistなら#to_i
じゃね?」「Hash#compact
はActiveSupportにあった気がする」「Rubyにもあるな?」「system "wget", "-w", wait_time.to_s, uri.to_s
は確かに事故りそう」「ないはずなのにcount_by
ってありそうな気がしてくるのが不思議↓」
User.all.count_by(&:name) rescue $!
# => #<NoMethodError: undefined method `count_by' for #<User::ActiveRecord_Relation:0x007f99d63135e0>
そこからyaml/JSON話に広がりました。
つっつきボイス: 「yaml嫌い!」「RONはともかくとしても」「JSONのケツカンマとかコメントできないとか本当残念」「JSON5はもっと普及してもよさそうなものなのに」「JSONといえばPostgreSQL(キリッ」「MySQLもJSONがんばってるし」
Ruby on Rails Security Project
Ruby on Rails Security Projectの最新のニュースレター #25が配信されたので、ざざっとリストアップします。
つっつきボイス: 「RoRのセキュリティ記事、新人の勉強会向け資料によさそう」「こういうのを1つ選んでスライドにして発表するとか」「発表ネタを探してる新人君はこのあたりからどうぞ」
オピニオン: RailsのCurrentAttributes
は有害
mail gemにヘッダーインジェクションの脆弱性
新しいApacheでは認証バイパスやDoS脆弱性を修正
日本語でも情報が出ています: JVNVU#98416507 Apache HTTP Web Server における複数の脆弱性に対するアップデート
ハッカーよ、汝自身をハックせよ
- 元記事: Hacker, Hack Thyself
つっつきボイス: 「thyはyourの古英語表現、シェークスピアぐらいの頃ですね」「汝の、みたいなニュアンス」「厨二病感出まくってそうw」「ファンタジー小説とかには欠かせない感じですね」
thouやthyは神様や皇帝の上から目線なセリフとかで使われる印象です。
フリーのAWSアカウントセキュリティ監査ツール
つっつきボイス: 「お、これ後で読も!」
認証方法ごとのセキュリティや使い勝手を比較
- 昔ながらのusername/password
- パスフレーズ
- 2要素認証
- SNSサインイン
- パスワードレス
- バイオメトリック認証
- ドングル認証
Webトラフィック傍受の広がりを理解する
GPG署名でGitHub commitのセキュリティを高める
RabbitMQの管理UIにXSS脆弱性
git-cop: git commitメッセージのスタイル違反をチェック
- リポジトリ: bkuhlmann/git-cop
configuration.ymlでスタイルを設定できるようです。
Running Git Cop...
d0f9bf40a09d10618bcf8a38a5ddd3bcf12fd550 (Brooke Kuhlmann, 3 seconds ago): This is a bogus commit message that is also terribly long and will word wrap
Commit Subject Length: Invalid length. Use 72 characters or less.
Commit Subject Prefix: Invalid prefix. Use: "Fixed", "Added", "Updated", "Removed", "Refactored".
Commit Subject Suffix: Invalid suffix. Use: ".".
3 issues detected.
つっつきボイス: 「プロジェクトで使うにはちょっと固すぎるかも」「オープンソースの方が向いているかも?」「Changelogを自動生成できるのがうらやましい」「そのためには相当気をつけてメッセージ書かないとなー」
そこからcommitメッセージの話題になりました。
つっつきボイス: 「いつのことだったか、commitメッセージにことごとく「◯◯修正」しか書いてないのを見たことあります」「commitメッセージにcommitした時間をがんばって手書きで入力しているのとかも」「...」「...」
vue-table: Vue.jsベースでテーブルを扱えるコンポーネント
- リポジトリ: ratiw/vue-table
Vue.jsベースでテーブルを作れます。★4,000超えの快挙です。
Bootstrapと併用したサンプルもWikiに掲載されています。
つっつきボイス: 「これもいい!」「管理画面でこれを使うくらいの所からVue.jsをはじめてみたい」
「Vue.jsとBootstrapといえばVueStrapもすごくいいですよ↓」
- 公式サイト: VueStrap
- リポジトリ: yuche/vue-strap
Vue.jsで書かれたBootstrapコンポーネントで、jQueryやBootstrap.jsを一掃できるそうです。
Railsに取り込まれそうな予感がちょっとしてきました。
Magic Wormhole: 他のPCから任意のサイズのファイル/ディレクトリを取得(HackerNewsより)
- リポジトリ: warner/magic-wormhole
PyCon 2016で発表されたようです。詳しくはスライド(PDF)や動画↓をどうぞ。
# 送信側
% wormhole send README.md
Sending 7924 byte file named 'README.md'
On the other computer, please run: wormhole receive
Wormhole code is: 7-crossover-clockwork
Sending (<-10.0.1.43:58988)..
100%|=========================| 7.92K/7.92K [00:00<00:00, 6.02MB/s]
File sent.. waiting for confirmation
Confirmation received. Transfer complete.
# 受信側
% wormhole receive
Enter receive wormhole code: 7-crossover-clockwork
Receiving file (7924 bytes) into: README.md
ok? (y/n): y
Receiving (->tcp:10.0.1.43:58986)..
100%|===========================| 7.92K/7.92K [00:00<00:00, 120KB/s]
Received file written to README.md
つっつきボイス: 「ざざっと見た感じ、相手のIPとかわからなくてもこの7-crossover-clockwork
みたいなコードを送るだけでファイル送受信できるってことか」「リンクを知っている人だけ見られるGoogleドキュメントのURL、みたいな感覚?」「さすがに受信側でもMagic Wormholeは起動しないといけないか」
CLIでささっとファイル交換したい人向けのようです。
Open Source Friday: 金曜日はオープンソースに貢献しよう(GitHub Trendingより)
- 公式サイト: https://opensourcefriday.com/
- リポジトリ: ossfriday/ossfriday
最初何のソフトウェアだろうと思ってリポジトリを追ってしまいましたが、これは一種のキャンペーンで、リポジトリは単なる公式サイトのアプリみたいです。
「オープンソースソフトウェアはみんなでつくるものです」「金曜日には、普段愛用しているオープンソフトウェアに数時間でも貢献しましょう」
Peatio: Rails製の仮想通貨交換プラットフォーム(GitHub Trendingより)
- リポジトリ: peatio/peatio
↑これがPeatio(貔貅)だそうです。日本語読みは「ひきゅう」。やはりというか中国発です。
Dexter: PostgreSQLのインデックスを自動作成(GitHub Trendingより)
つっつきボイス: 「インデックス化のヒントくれるならいいけど、自動作成まではちょっとな~」「そこまで全自動ではないみたいですヨ」「SQLログから解析するのか」「PerconaのPostgreSQL版みたいな感じなのかな」
記事をまとめているときに気づきましたが、DexterではHypoPGというhypothetical indexをPostgreSQLにインストールするよう指示しています。このhypothetical indexという用語はまだ日本語になっていないようですが、Microsoft SQL Serverには搭載されているようです。
- 公式サイト: HypoPG
ついでに、Hypothetical Index Strategy Calculatorというサイトも見つけました。
AirBnB製のJavaScriptスタイルガイド
★54,000台という凄まじさです。スタイルの多くに理由が書かれているのがいいですね。こういうの大事だと思います。
例:
3.2 参照を再代入する場合はlet
を使うこと(var
やeslintのno-var
やjscsのdisallowVar
は使わない)
理由: let
がブロックスコープだから(var
のような関数スコープではない)
つっつきボイス: 「この★の数からいって、これがJavaScript界のスタンダードなのかな」
番外: Quick, Draw!の大量の画像データ
Quick, Drawより(Quick, DrawはGoogleのサービスです)
昨年11月のRailsウォッチでご紹介したQuick, Draw!の/data
ディレクトリを開くと、これまでに登録されたおびただしい手書き画像データがずらりと並んでいます。50 millionだそうです。
Quick, Drawより(Quick, DrawはGoogleのサービスです)
書き順までしっかりデータ化されています。
今週は以上です。
バックナンバー(2017年度)
- 週刊Railsウォッチ(20170623)gemを見極める7つのコツ、mixinがよくない理由、重いページをrender_asyncで軽減ほか
- 週刊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など)です。