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

週刊Railsウォッチ(20191223前編)Railsセキュリティ修正6.0.2.1と5.2.4.1リリース、Ruby 2.7.0-rc2リリース、ActiveRecordのコールバック回避ほか

こんにちは、hachi8833です。今年最後のRailsウォッチ前編をお送りします。Ruby 2.7のカウントダウンが始まっていますので、クリスマスにはリリースされるでしょう。

その後21日にrc2がリリースされました。

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください

お知らせ: 週刊Railsウォッチ「第18回公開つっつき会」(無料)

第18回目公開つっつき会は、来年1月09日(木)19:30〜にBPS会議スペースにて開催されます。今回から会場のPubスペースが隣の部屋に移ります。

週刊Railsウォッチの記事やここだけの話にいち早く触れられるチャンス!発言・質問も自由です。皆さまのお気軽なご参加をお待ちしております🙇。

臨時ニュース: Railsセキュリティ修正6.0.2.1と5.2.4.1がリリース

Rackで情報漏えい/セッションハイジャックの脆弱性が見つかったとのことです。どちらもRackのバージョンアップとAction Packのみの修正です。

ActionDispatch::Session::MemcacheStoreがまだ脆弱なので、dalli gemもアップデートが必須。
Changelogより大意

オレオレアプリは対応しました。

追記(2019/12/24): 上記セキュリティ修正でredis-storeがエラーになる可能性

redis-storeをお使いの方は、本件が解決するまでセキュリティアップデートを待つ必要がありそうです。
なお、同issueのコメントではredis-storeの修正で解決できると追記されていますが、現時点ではまだredis-storeにマージされていません。

Rails: 先週の改修(Rails公式ニュースより)

お詫び: 今回の録画に音声が入っていなかったため、最小限のつっつきボイスとなっています🙇🙇。

以下から見繕いました。

delegateがRuby 2.7の...記法に対応

# activesupport/lib/active_support/core_ext/module/delegation.rb#L202
- definition = /[^\]]=$/.match?(method) ? "arg" : "*args, &block"
+ definition = if /[^\]]=$/.match?(method)
+ "arg"
+ elsif RUBY_VERSION >= "2.7"
+ "..."
+ else
+ "*args, &block"
+ end

以下は先週も貼りましたが一応。

参考: Ruby 2.7 の変更点 - 「...」で全引数渡し - @tmtms のメモ
参考: Ruby 2.7 adds shorthand syntax for arguments forwarding – Saeloun Blog


つっつきボイス:「...はRuby 2.7の新機能か😳」「"*args, &block"と同等なんですね」

参考: $@ - シェルスクリプトに渡されたすべての引数

Ruby: Kernelの特殊変数を$記号を使わずに書く

bundle exec rubyでテストを実行できるよう修正

require: cannot load such file -- abstract_unit (LoadError)のようなエラーはRailsが初めての人にとってうれしくないので、いい感じにシンプルにした。またテストの依存関係も明確になり、サブフォルダでテストを実行できるようにもなった。
同PRより大意


つっつきボイス:「Railsに慣れていない人がくじけないようにとのことです」「修正ファイル144個は多いな〜😆」「修正されたissue #34025↓を見るとbundle exec ruby test/cache/stores/mem_cache_store_test.rbって実行してエラーになってたけど、こんなふうに実行したことないし😆」

yearが未定義の場合の扱いを修正

# actionview/lib/action_view/helpers/date_helper.rb#L832
def select_year
- if !2019/12/23time || 2019/12/23time == 0
+ if !year || 2019/12/23time == 0
val = "1"
middle_year = Date.today.year
else
val = middle_year = year
end
if @options[:use_hidden] || @options[:discard_year]
build_hidden(:year, val)
else
options = {}
options[:start] = @options[:start_year] || middle_year - 5
options[:end] = @options[:end_year] || middle_year + 5
options[:step] = options[:start] < options[:end] ? 1 : -1 options[:leading_zeros] = false options[:max_years_allowed] = @options[:max_years_allowed] || 1000 if (options[:end] - options[:start]).abs > options[:max_years_allowed]
raise ArgumentError, "There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter."
end
build_select(:year, build_year_options(val, options))
end
end

つっつきボイス:「yearが定義されていない場合今までエラーになってたのね😳」「テストを見るとわかりやすいかも↓」

# actionview/test/template/date_helper_test.rb#473
def test_select_year_with_empty_hash_value_and_no_start_year
expected = +%(<select name="date[year]">\n)
</select>
<select name="date[year]">expected << %(
<option value="2014">2014</option>\n
<option value="2015">2015</option>\n
<option value="2016">2016</option>\n
<option value="2017">2017</option>\n
<option value="2018">2018</option>\n)
</select>
<select id="date_year" name="date[year]">expected << "
</select>\n"

Date.stub(:current, Date.new(2018, 12, 18)) do
assert_dom_equal expected, select_year({ year: nil, month: 4, day: nil }, { end_year: 2018 })
end
end

マイグレーションのremove_columnsをリバーシブルに

removetype:を書いておけばリバースできるようになるそうです。

# 同PRより
class InvertibleChangeTableMigration < SilentMigration
def change
change_table("horses") do |t|
t.column :name, :string
t.remove :remind_at, type: :datetime
end
end
end

つっつきボイス:「マイグレーションのchangeremoveを書けるようになったそうです」「自分は使わないかな〜😆」

番外: 細かな修正

# railties/lib/rails/generators/rails/app/templates/config/puma.rb#L7
-threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
+threads_count = Integer(ENV.fetch("RAILS_MAX_THREADS", "5"))
threads threads_count, threads_count

つっつきボイス:「#28499は↑今までブロック渡しだったのを引数に変えた」「#38020はAction Textのドキュメントに補足↓」「そういえばWebpacker関連の記述って今のRailsガイドにほとんどありませんね😆」「WIPなガイドは他にもありますし☺️」

# guides/source/action_text_overview.md#L47
-Run `rails action_text:install` to add the Yarn package and copy over the necessary migration.
-Also, you need to set up Active Storage for embedded images and other attachments.
-Please refer to the [Active Storage Overview](active_storage_overview.html) guide.
+Run `rails action_text:install` to add the Yarn package and copy over the necessary migration. Also, you need to set up Active Storage for embedded images and other attachments. Please refer to the [Active Storage Overview](active_storage_overview.html) guide.
+
+After the installation is complete, a Rails app using Webpacker should have the following changes:
+
+1. Both `trix` and `@rails/actiontext` should be required in your JavaScript pack.
+
+```js
+// application.js
+require("trix")
+require("@rails/actiontext")
+```
+
+2. The`trix` stylesheet should be imported into `actiontext.scss`.
+
+```scss
+@import "trix/dist/trix";
+```
+
+Additionally this `actiontext.scss` file should be imported into your stylesheet pack.
+
+```
+// application.scss
+@import "./actiontext.scss";
+```

Rails

RailsとDDD

RailsはActiveRecordが密結合で実現しているためDDDのモデリングの考え方と相性が悪く、レイヤードアーキテクチャをやろうとすると型がないことなどDDDの考え方が適応しにくい
同記事より


つっつきボイス:「上みたいな記事を割と見かけるんですがやっぱり難しいんでしょうか?」「RailsでDDDをやるのは簡単ではありませんね🧐: Active Recordモデルを永続化に専念させるとか、いろいろやらないといけなくなりますし」「そうでしたか...RailsとDDDの記事は新しいのが少ないのはそういう事情があるのかも?🤔」「どうしてもやりたいならHanamiとかにする方がいいんじゃね?😆」

参考: Rails 歴5年の僕が Laravel で開発するようになって思ったこと。|Kurashicom Engineers' Blog|note

Active Recordのコールバックを回避(Ruby Weeklyより)

Active Recordのコールバックにビジネスロジックを実装すべきでないと強く信じている。
同記事より抜粋

# 同記事より
class Address
attr_accessor :disable_geolocation
before_save :set_geolation, unless: :disable_geolocation

private

def set_geolocation
# Hit some API or something...
end
end

つっつきボイス:「disable_geolocationがtrueならコールバックしないようにしてる」「そういえば銀座Rails#15でもコールバック消し去りたい話が出てたのを見た覚えがあったんですが、この辺のツイートにあったのをやっと見つけました↓」「kamipoさんとyahondaさんの対談ですね☺️」

「とりあえず言っておきたいのは、コールバックとconcernsは相性が悪い」「あぁ!」

「そういえばkazzさんはコントローラのbefore_actionコールバックは例外的に好きって言ってました」「コントローラのbefore_actionも気をつけないとカオスになりますよ💀」「うぅ😢」

RubyConf 2019@Nashvilleまとめ


同記事より


つっつきボイス:「手描きのまとめが素敵だなと思って❤️」「でも他の人が読むにはつらいという😆」

その他Rails

つっつきボイス:「RailsとReactとTerraformとスクラム開発やれたらマジ有能」


つっつきボイス:「Rackは思ったより難しくないし記事も多いので、どんどん作って動かしてみるのがいいと思います😋」


同リポジトリより

参考: 海外記事翻訳シリーズ 【第 2 回】 Rack 仕様
参考: Rails と Rack - Railsガイド
参考: 第23回 Rackとは何か(1)Rackの生まれた背景:Ruby Freaks Lounge|gihyo.jp … 技術評論社


前編は以上です。

おたより発掘

バックナンバー(2019年度第4四半期)

週刊Railsウォッチ(20191217後編)Ruby 2.7の変更点とパターンマッチング、依存性自動アップデートツール、Stack Overflowアンケート2019ほか

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

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

Rails公式ニュース

Ruby Weekly


CONTACT

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