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

週刊Railsウォッチ: rodauth-rails gem作者の解説記事、turbo-railsの有料チュートリアルほか(20221025前編)

こんにちは、hachi8833です。Kaigi on Rails 2022が盛況のうちに終わりましたね。主催者・運営・スポンサー・参加者の皆さまお疲れさまでした&ありがとうございます!

週刊Railsウォッチについて

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

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

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

🔗 新規マイグレーションのカラム/テーブル管理で無効なオプションが指定されるとraiseするようになった

マイグレーションのcreate_tableメソッドやadd_columnメソッドなどに無効なオプションを渡すと、オプションを無視せずにraiseするようになる。なおオプションの検証は、新規作成したマイグレーションに対してのみ適用される。
Guo Xiang Tan, George Wambold
同Changelogより


つっつきボイス:「有効なオプションをホワイトリスト化して、無効なオプションが渡されたらエラーになるようにしたんですね↓」

# activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb#L1561
-       def extract_table_options!(options)
-         options.extract!(:temporary, :if_not_exists, :options, :as, :comment, :charset, :collation)
+       def valid_table_definition_options
+         [:temporary, :if_not_exists, :options, :as, :comment, :charset, :collation]
+       end
+
+       def valid_primary_key_options
+         [:limit, :default, :precision]
+       end
+
+       def validate_create_table_options!(options)
+         unless options[:_skip_validate_options]
+           options
+             .except(:_uses_legacy_table_name, :_skip_validate_options)
+             .assert_valid_keys(valid_table_definition_options, valid_primary_key_options)
+         end
        end

「今だと無効なオプションを渡しても無視されるだけだったかも」「たしかadd_columnメソッドでnull: truenil: trueと間違えてもエラーにならなかった覚えがある」「そうそう、ミスったのに気づかないまま先に進んで詰んだりしますよね」「大事な改修👍」

参考: Rails API add_column -- ActiveRecord::ConnectionAdapters::SchemaStatements

🔗 Range#to_sのドキュメントを更新

動機/背景
このプルリクを作成した理由は、Rails 7では#43772からto_s(:format)が非推奨化されてto_fsが推奨されるようになったため。反映のためドキュメントを更新した。
同PRより


つっつきボイス:「Ruby 3.1の最適化に伴う以下の改修↓に合わせてドキュメントを更新したそうです」「非推奨化されたのはto_sそのものではなくto_s(format)というformatオプション付きの場合でしたね: to_sそのものは式展開で暗黙に引数なしで呼び出されたりするので引き続き必要」「to_fsto_formatted_sのエイリアスなのか」

参考: Deprecate to_s(format) in favor of to_formatted_s(format) by rafaelfranca · Pull Request #43772 · rails/rails

🔗 Rails.application.deprecatorsが追加

このプルリクはRails.application.deprecatorsを追加する。これはdeprecatorsのマネージドコレクションを返す。
このコレクションでは個別のdeprecatorsを追加・取り出しできる。

Rails.application.deprecators[:my_gem] = ActiveSupport::Deprecation.new("2.0", "MyGem")
Rails.application.deprecators[:other_gem] = ActiveSupport::Deprecation.new("3.0", "OtherGem")

コレクションのコンフィグメソッドは、コレクション内のすべてのdeprecatorsに影響する。

Rails.application.deprecators.debug = true

Rails.application.deprecators[:my_gem].debug
# => true
Rails.application.deprecators[:other_gem].debug
# => true

さらに、渡されたブロック内のコレクションにあるすべてのdeprecatorsを抑制できる。

Rails.application.deprecators.silence do
  Rails.application.deprecators[:my_gem].warn    # => silenced (no warning)
  Rails.application.deprecators[:other_gem].warn # => silenced (no warning)
end

つっつきボイス:「割と大きなプルリク」「Deprecatorsクラスが新たに追加されていますね」「個別の非推奨化処理を新たにこのクラスに集約するようにした感じかな」「Rails.application.deprecatorsでアクセスしてデバッグしたり非推奨化メッセージを出し分けたりできるようですね」「この機能が追加された経緯がわからないけど、どこか別のところで議論したのかもしれませんね」

# activesupport/lib/active_support/deprecation/deprecators.rb
# frozen_string_literal: true

module ActiveSupport
  class Deprecation
    # A managed collection of deprecators. Configuration methods, such as
    # #behavior=, affect all deprecators in the collection. Additionally, the
    # #silence method silences all deprecators in the collection for the
    # duration of a given block.
    class Deprecators
      def initialize
        @options = {}
        @deprecators = {}
      end

      # Returns a deprecator added to this collection via #[]=.
      def [](name)
        @deprecators[name]
      end
...

参考: § 3.13.10 config.active_support.deprecation -- Rails アプリケーションを設定する - Railsガイド

🔗 Turbo v7.2.2がリリース


つっつきボイス:「この間リリースされたTurbo v7.2.0(ウォッチ20221011)に続いてV7.2.2がリリースされました」「v7.2.1は誤ってnpmにプッシュしてしまったのでスキップしたのね」

「ところでTurbo v7.2.0の更新情報↓をあの後少し見てみたんですが、更新が結構多いけどまだTurboのドキュメントに反映されていないようです」「互換性のなくなる更新はドキュメントにすぐ反映されないと困るけど、v7.2.0は機能追加とバグ修正だけのようなのでドキュメントは後追いでもいいんじゃないかな」「それもそうですね」

参考: Release v7.2.0 · hotwired/turbo
参考: Events -- Turbo Reference

🔗Rails

🔗 RodauthをRailsと統合するのに必要だったこと(Ruby Weeklyより)

↑翻訳許可をいただいたので近日中に公開します。


つっつきボイス:「著者のJankoさんは、Jeremy EvansさんのRodauthという認証gemをRailsに統合するためにrodauth-railsとrodauth-modelというgemを作って、SequelとActive Recordのどちらでも使えるようにしたようです」

jeremyevans/rodauth - GitHub

janko/rodauth-rails - GitHub

janko/rodauth-model - GitHub

「認証周りのコードはややこしくなりがちですよね」「RodauthのREADMEを見てみると想像以上に機能が強力そうな感じ」「ほんとだ、SMS経由の2要素認証とかいろいろ機能があって割とすぐ使えそうな雰囲気かも」「Rodauthはちゃんと更新されているようだし、一定のファンもいそうですね」「認証gemはメンテされていることが大事ですね: されてないと辛すぎるので」

「RodauthはこれもJeremy EvansさんのRodaというルーティングエンジンを元にしているんですが、どちらもREADMEがとてもよく書けていたのでだいぶ前にそれぞれ翻訳したことがあります↓」

Ruby: 認証gem「Rodauth」README(更新翻訳)

Ruby: 高速/高性能ルーティングエンジンgem「Roda」README: 前編(翻訳)

なおRodauthはRodaがなくても利用できるそうです↓。

You can use Rodauth even if your application does not use the Roda web framework.
Rodauth READMEより


以下はJeremy Evansさんによる2020年のRodauth 2.0解説動画です(現在のRodauthは2.26.0)。

🔗 rubocop-migration gem

r7kamura/rubocop-migration - GitHub


つっつきボイス:「r7kamuraさんがstrong_migrationにヒントを得てrubocop-migrationというgemを作ったそうです」

ankane/strong_migrations - GitHub

「たしかstrong_migrationは書き方がよくないマイグレーションをチェックするgemですね」「たしかにRuboCopでチェックできると嬉しい」「RuboCopでやるべき感ある」「RuboCop-Railsにもマイグレーションとの関連が強い項目はいくつもありますね↓: モデルにuniquenessバリデーションを追加したのにuniqueインデックスを追加しないと怒られるcopとか」「なるほど」「でも今後もしかするとマイグレーション関連をgemに切り出してrubocop-migrationと一緒にしようみたいな話が持ち上がるかもしれませんね」「合流できたらいいですね」

参考: Rails :: RuboCop Docs

🔗 VSCodeのDev ContainerでRailsを動かしてruby/debugを使う


つっつきボイス:「Dev Containerの中でruby/debugを使えるようにしたという記事です」「Dev ContainerはVSCodeで使えるリモートコンテナ開発環境の機能ですね: コンテナになる分、通信周りが複雑になりがち」「中でruby/debugを動かしてvscode-rdbgと通信するとそうなりそう」「rdbgが使うデバッグ用ポートを開いてVSCodeをアタッチするとかが必要になるでしょうね」

参考: Developing inside a Container using Visual Studio Code Remote Development

🔗 Rails6〜7で追加された便利メソッド


つっつきボイス:「先週のcompact_blankウォッチ20221019)を調べていて見つけた記事です」「compact_blankは他の方法でも書けるけど、パフォーマンス上有利なので知っていたら使いたいメソッドですね」

「6.0からenumを宣言するとnot_付きのスコープも生成されるようになったのは便利↓」

# 同記事より
class Post < ActiveRecord::Base
  enum status: [:drafted, :active, :trashed]
end

Post.not_drafted # => where.not(status: :drafted)
Post.not_active  # => where.not(status: :active)
Post.not_trashed # => where.not(status: :trashed)

in_order_ofは知っていると便利: これなしで同じことをやろうとすると割と面倒ですね」

# 同記事より
Article.in_order_of(:id, [1, 5, 3])
# SELECT "articles".* FROM "articles"
# ORDER BY FIELD("articles"."id", 1, 5, 3)
# WHERE "articles"."id" IN (1, 5, 3)

Rails 7: クエリ結果を任意の順序にできるActiveRecord::QueryMethods#in_order_of

「記事でちょっとだけ触れているinvert_whereはたしか議論になっていましたね↓」「invert_whereはスコープが複数になったりすると知らないうちに意味が変わったりするので注意しないと危険」

参考: Rails 7で導入される invert_where メソッドが危険そうだったので調べた - pockestrap

Rails 7のActive Recordにinvert_whereメソッドが追加される(翻訳)

🔗 rebuilding turbo-rails Tutorial


つっつきボイス:「以前無料のTurbo Railsチュートリアル↓を紹介しました(ウォッチ20220411)が、その関連コンテンツとしてRailsエンジンをturbo-railsで再構築するチュートリアルを有料でリリースしたそうです」「お、なかなかよさそう👍」「値段を見たら49ユーロですって」「今の円安状況だと7千円超えるのか〜」「円安つらい」

参考: Learn Hotwire and Turbo with a free Rails 7 tutorial

「ところで、こういう教材を見ていると懐かしのRailsCastsを思い出してしまいますね↓」「RailsCastsは自分もお世話になりました」「RailsCastsはもう更新されていないけど、サイトは何年か前に復活して全コンテンツが完全無料になりましたね」

参考: Ruby on Rails Screencasts - RailsCasts

🔗 その他Rails

つっつきボイス:「Railsガイドが先ごろリリースした協賛プランに早速SmartHRさんからの協賛をいただきました」

参考: 協賛プラン - 全国のRailsエンジニアに貢献する - Railsガイド
参考: 📕 Railsガイド『協賛プラン』をリリース|YassLab 株式会社|note


「お〜、最近のRailsチュートリアルはこんなに充実しているんですね」「もともと自分が翻訳に参加したときは、上の図真ん中のWebテキストの半分程度を翻訳したんですが、YassLabの皆さんの継続的な改善のおかげで、今では翻訳も解説動画やそれ以外の要素も強化されました」「Railsチュートリアルは自主学習用の教材・コンテンツとしてよくできているとしみじみ思います👍」

参考: Ruby on Rails チュートリアル:プロダクト開発の0→1を学ぼう


前編は以上です。

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

週刊Railsウォッチ: Ruby技術者認定試験再受験無料キャンペーン、Starlink日本で販売開始ほか(20221019後編)

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

Rails公式ニュース

Ruby Weekly


CONTACT

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