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

週刊Railsウォッチ: RailsConf 2022が5月17〜19日開催、認可機能解説記事ほか(20220418前編)

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

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

珍しくChangelogに更新がありませんでした。更新も少なめでドキュメントの修正が主でした。

🔗 Railsコンソールのreload!でeager loadingされない問題を修正

以下のSTIクラス構造でconfig.eager_load = trueを設定したとする。

# config/development.rb
config.eager_load = true
# app/models/class_a.rb
class ClassA < ActiveRecord::Base
  def self.types
    descendants.map(&:name)
  end
end
# app/models/class_b.rb
class ClassB < ClassA
end
rails c
Loading development environment (Rails 4.2.6)
irb(main):001:0> ClassA.types
=> ["ClassB"]
irb(main):002:0> reload!
Reloading...
=> true
irb(main):004:0> ClassA.types
=> []

期待される動作: reload!を実行すると、eager load済みのコンテンツがすべてリロードされる。
実際の動作: reload!を実行しても、eager load済みのコンテンツがすべてリロードされていないように見える。
issue #24819より


つっつきボイス:「修正したのはZeitwerk↓でおなじみの@fxnさんでした」「issueによると、eager lodingされたものをRailsコンソールでreload!しても効かない問題が修正されたんですね」

参考: 定数の自動読み込みと再読み込み (Zeitwerk) - Railsガイド

🔗 test環境での無効なスキーマダンプの扱いを修正


つっつきボイス:「これもissueを見ると、schema_dump: falseを指定することでマイグレーションなどでスキーマダンプを作成しないようにできるらしい↓」「この機能知らなかった」「その機能がtest環境でちゃんと動いていなかったのが修正されたようですね」

# b/config/database.yml
@@ -8,6 +8,7 @@ default: &default
   adapter: sqlite3
   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
   timeout: 5000
+  schema_dump: false

🔗 bladeをアップグレードしてRuby 3.2をサポート

# Gemfile#L110
group :view do
- gem "blade", github: "javan/blade", require: false, platforms: [:ruby]
+ gem "blade", require: false, platforms: [:ruby]
  gem "sprockets-export", require: false
end

つっつきボイス:「bladeって何だろう?」「PHPのBladeではなさそう」「SprocketsでJavaScriptのビルドとテストを行うツールキットですって」

javan/blade - GitHub

参考: Bladeテンプレート 5.5 Laravel

「Bladeのリポジトリを見ると、Trix(Action Text)やTurbolinksやAction Cableで使われていると書かれてる」「Sprocketsでバンドルされるものもテストが必要なので、そのために使われているのかもしれませんね」

# javan/blade
# .blade.yml
…
build:
  logical_paths:
    - widget.js
  path: dist
  js_compressor: uglifier # Optional

🔗 タイムゾーンのテストにUTC-12も追加

# activesupport/test/time_zone_test.rb#L404
  def test_parse_string_with_timezone
    (-11..13).each do |timezone_offset|
    (-12..13).each do |timezone_offset|
      zone = ActiveSupport::TimeZone[timezone_offset]
      twz = zone.parse("1999-12-31 19:00:00")
      assert_equal twz, zone.parse(twz.to_s)
    end
  end

つっつきボイス:「UTC-12というタイムゾーンをこれで初めて知りました」「UTC+12ではなくマイナスになってる?」

参考: UTC-12 - Wikipedia
参考: UTC+12 - Wikipedia

「Wikipediaを見るとこんなことが書かれてた↓」「該当する地域に住んでる人がいないタイムゾーンだとは」「でもUTC+12だと住んでいる人がいる」「Anywhere on Earthという概念があるのね」

世界で最も西の標準時であり、地球上で最も遅く新しい1日が始まる。このため、これによる締め切り等の日時を Anywhere on Earth (AoE、またはAOEとも) と表記することがよくある。
UTC+12と同じ時刻だが、日付が1日遅れる。
(略)
現在この地域に定住する住民はいない。

https://ja.wikipedia.org/wiki/UTC-12より



https://ja.wikipedia.org/wiki/UTC+B12より

「UTC-13から-23とか幅があるとは知らなかった」「プラスの方にもUTC+13から+23とか幅がありますね」「すぐには思いつかないけど、これが欲しいときもあるんでしょう」「歴史的な理由でできたのかも?」「タイムゾーンって実はちょくちょく更新されたりするので不変ではないんですよね」


「そういえばEUや米国でもサマータイムやめる動きがあるみたいですね」「EUはまだ審議中か」「米国のサマータイム恒久化って、年中サマータイムにするということ?」「よくわからない...」

参考: これで最後?EUが夏時間へ 廃止検討するも議論進まず:朝日新聞デジタル
参考: 米上院、夏時間恒久化法案を可決 | ロイター

「それにしても日本にサマータイムがなくてよかった」「戦後の一時期にだけありましたけどね↓」「知らなかった〜」

参考: 夏時刻法 - Wikipedia

🔗 debug.logファイルを100MBでローテーション

# activerecord/test/support/connection.rb#L21

  def self.connect
    ActiveRecord.async_query_executor = :global_thread_pool
    puts "Using #{connection_name}"
-   ActiveRecord::Base.logger = ActiveSupport::Logger.new("debug.log", 0, 100 * 1024 * 1024)
+   ActiveRecord::Base.logger = ActiveSupport::Logger.new("debug.log", 1, 100 * 1024 * 1024)
    ActiveRecord::Base.configurations = test_configuration_hashes
    ActiveRecord::Base.establish_connection :arunit
    ARUnit2Model.establish_connection :arunit2
  end

つっつきボイス:「これはいい改修👍」「debug.logってものすごく大きくなったりしますよね」

🔗 rails-ujs関連のドキュメント更新


つっつきボイス:「非推奨になったrails-ujs関連のドキュメントが削除・更新されたそうです」「お、リンクやボタンでdata-remoteが非推奨になるのか」「data-methodも今後はdata-turbo-methodになるのね」「UJSがなくなるならそうなるのもわかる」

参考: Performing Visits With a Different Method: Turbo Handbook
参考: data-* - HTML: HyperText Markup Language | MDN

🔗Rails

🔗 Railsコントローラで認可機能を使う(Ruby Weeklyより)


つっつきボイス:「PunditとCanCanCanの比較もされていますが、認可(authorization)機能の解説の方が多い印象でした」

varvet/pundit - GitHub

CanCanCommunity/cancancan - GitHub

参考: 認可 (セキュリティ) - Wikipedia

「Cancancanはの認可はコントローラやビュー周りにコードを記述するのに対し、Punditはドメインモデルに記述するという話も盛り込まれてますね」「記事最後のまとめを見るのが早いかも」

参考: ドメインモデル - Wikipedia

「ざっくりとですが、APIベースのAPIサーバーだとCanCanCan方式の方が扱いやすくて、リソースベースで設計する場合はPunditの方が使いやすい印象があります」「記事でもCanCanCanの方がとっつきやすいだろうと書かれてますね」

「CanCanCanはわかりやすいのでシンプルなものを構築するときはいいんだけど、複雑なネステッドリソースを扱うとすぐ破綻するので、ドメインモデルが複雑になることがわかっているならPunditの方が合いやすいかな」「ふむふむ」「持っている権限に応じてURLそのものが変わるならCanCanCanは比較的わかりやすいけど、同じURLだけど見える内容や振る舞いが権限に応じて変わるなら、Punditのように呼び出しコンテキストによってどう変わるかを宣言できる方が扱いやすい感じ」

🔗 スライド『予防に勝る防御なし』


つっつきボイス:「@t_wadaさんのこのスライドはよかった👍: ここではPHPで説明しています」「設計話だ」「イミュータブルのような定番の話もあるけど、特に後半に学びが多かった」

「まず、SimpleとEasyを混ぜてはいけないという話がわかりやすくていいですね↓」

「fail firstに関連して例外とアサーション(表明)を区別する話もすごくよかった↓」「あってはならないことはアサーションで書く、ふむふむ」「アサーションはテストコードで書く印象があって、Rubyの通常のコードでアサーションをあまり書かない感じなんですが(Javaなどでは通常のコードにもアサーションを書けます)、例外とアサーションを使い分けることでわかりやすくなるというのは学びでしたね」「なるほど」「設計の話は人によって刺さり方が違うものですが、自分はこの2つが刺さりました」

参考: 表明 (プログラミング) - Wikipedia

🔗 DDDの「腐敗防止層」

「こちらの記事も設計の話です」「腐敗防止層という言葉が興味深い」「著者のミノ駆動さんをちょうどこの間Twitterでフォローしたところです」「今度設計の本を出すんですって↓」「予約しとこうっと」「電書出たら買います」

参考: 『良いコード/悪いコードで学ぶ設計入門 』を出版します|ミノ駆動|note

「この図↓のインフラ層の何とかgatewayが腐敗防止層なのね」「Adapterパターンを上向きと下向きの両方に使う感じかな」「固いクラス設計はだいたいRubyよりJavaの方が相性がいいんですよね」「DDD(ドメイン駆動設計)は、DDDをちゃんとやれるエンジニアが常に張り付いて管理する必要があるのがちょっと大変」


同記事より

参考: ドメイン駆動設計 - Wikipedia

🔗 country_select: 国名セレクタ用gem(Ruby Weeklyより)

countries/country_select - GitHub


つっつきボイス:「取り上げていそうでいなかった国名セレクタを作るgemですね」

<!-- 同リポジトリより -->
<%= form_for User.new, url: root_url do |f| %>
  <%= f.country_select :country_code %>
<% end %>

「Webアプリとかの国名セレクタって皆さんどうやって作ってるんでしょう?」「手頃なyamlファイルを見つけるとかでやっていると思いますけどね」「国名セレクタぐらいならgemでやらなくても手作りでいいのではという気持ちはある」

「それに国名のリストを常に最新に保つ必然性は実はあまりなくて、むしろ途中でgemを更新して国名リストが変わったりするとアプリケーションの挙動に影響する方が困るかも」「それもそうですよね」

「国名が変わったりすることってあるんですか?」「国際的に承認されている国やそうでない国のリストが変動することはあるでしょうね」「ローカライズ業界だと、国名の翻訳後にカントリーチェックというレビューが入ることがありました: 特定の国名を訳出していいかどうかを判断する一種のポリティカルチェックです」「たしかに国名の扱いはいろいろデリケート」

参考: 国名コード - Wikipedia

🔗 その他Rails


つっつきボイス:「Zeitwerkの@fxnさんがRailsConfのキーノートスピーチを務めるそうです」「オレゴン州ポートランドで5月17日〜19日開催、リモート参加もありか」「もう来月じゃないですか」「さすがスケジュールにも錚々たる登壇者が揃ってる↓」

参考: Schedule | RailsConf 2022


前編は以上です。

バックナンバー(2022年度第2四半期)

週刊Railsウォッチ: HashieでRubyのハッシュを強化、最近のRubyコア解説記事ほか(20220412後編)

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

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

Rails公式ニュース

Ruby Weekly


CONTACT

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