- Ruby / Rails関連
週刊Railsウォッチ(20210517前編)Bootstrap 5リリース、productionでSQLiteがwarning表示、rails-ujsの舞台裏ほか
こんにちは、hachi8833です。
🔗Rails: 先週の改修(Rails公式ニュースより)
今回は以下のコミットリストのChangelogを中心に見繕いました。
🔗 CSPヘッダーのサポートを2つ追加
つっつきボイス:「require-trusted-types-for
とtrusted-types
、知らないヘッダーだ」「issue #42034を見ると、MDNでexperimentalとなってるそうです」「これらはサーバー側が返すヘッダなので、Railsが対応してくれることでexperimentalな最新の機能を利用できるということですね」
参考: CSP: require-trusted-types-for
- HTTP | MDN
参考: CSP: trusted-types
- HTTP | MDN
# actionpack/lib/action_dispatch/http/content_security_policy.rb#L108
MAPPINGS = {
self: "'self'",
unsafe_eval: "'unsafe-eval'",
unsafe_inline: "'unsafe-inline'",
none: "'none'",
http: "http:",
https: "https:",
data: "data:",
mediastream: "mediastream:",
blob: "blob:",
filesystem: "filesystem:",
report_sample: "'report-sample'",
strict_dynamic: "'strict-dynamic'",
+ script: "'script'",
ws: "ws:",
wss: "wss:"
}.freeze
DIRECTIVES = {
base_uri: "base-uri",
child_src: "child-src",
connect_src: "connect-src",
default_src: "default-src",
font_src: "font-src",
form_action: "form-action",
frame_ancestors: "frame-ancestors",
frame_src: "frame-src",
img_src: "img-src",
manifest_src: "manifest-src",
media_src: "media-src",
object_src: "object-src",
prefetch_src: "prefetch-src",
+ require_trusted_types_for: "require-trusted-types-for",
script_src: "script-src",
script_src_attr: "script-src-attr",
script_src_elem: "script-src-elem",
style_src: "style-src",
style_src_attr: "style-src-attr",
style_src_elem: "style-src-elem",
worker_src: "worker-src"
script_src: "script-src",
script_src_attr: "script-src-attr",
script_src_elem: "script-src-elem",
style_src: "style-src",
style_src_attr: "style-src-attr",
style_src_elem: "style-src-elem",
+ trusted_types: "trusted-types",
worker_src: "worker-src"
}.freeze
参考: Rails アプリケーションのセキュリティ対策(CORS/CSP/HSTS)
🔗 SQLiteをproductionで使うとwarningを出力
SQLiteをproductionで実行するとwarningをログ出力する。
warning出力はconfig.active_record.sqlite3_production_warning=false
で無効にできる。
closeするissue: #34715
同PRより
つっつきボイス:「SQLiteをproductionで使うとwarningを出すようになったそうです」「アプリの性質によってはSQLiteをproductionで使う可能性もなきにしもあらずですし、warning出すほどでもない気はしますけどね」「#34715のコメントには『自分はproductionで問題なくSQLite使ってるよ』という書き込みもありました」「コンフィグでwarning出さないようにできるのか」
参考: SQLite Home Page
「現実問題としてSQLiteをproductionで使う可能性はかなり低いと思うので、多いのは『間違ってSQLiteを使ってしまう』ケースでしょうね」「それありそうですね」
参考: SQLiteと他のデータベースの違いを紹介します。「SQLiteの特徴を教えてください」 - Python学習チャンネル by PyQ
ですが、SQLiteができるロックはそれほど柔軟でないのが特徴です。ロックする範囲をデータベース全体でしか制御できない(テーブル単位、行単位でのロックができない)特徴を持っています。
また、SQLiteはローカルのファイルを直接データベースとして扱うので、複数のサーバーとネットワークごしに接続するのには不向きです。Webサーバーを複数台起動する場合などはMySQLやPostgreSQLなどを使うほうが良いでしょう。
blog.pyq.jpより
「データベースの内容がユーザーから一切変更できないようなアプリなら、そうしたデータの保存にSQLiteを使うこともありますし、Androidのゲームアプリなんかでは、SQLiteのファイルをソフトウェア本体にbundleしてSQL互換アクセスできるread onlyなマスタデータベースとして使うなんてこともありますよね」「なるほど」「特に最近のRailsはマルチプルデータベースに対応しているので、変更が生じないマスターデータについてはSQLiteに入れるという選択肢はありでしょうね」「たしかに、私のenno.jp↓というアプリもデータ更新は管理者しか行わないので本当はSQLiteにしたかったんですけど、HerokuではSQLiteを利用できない仕様になってました😢」
「SQLiteは読み出し専用で使っている分には決して遅くありませんし、SQLiteのようなファイルベースのDBにはひとついい点があるんですよ: データがすべてOSのファイルキャッシュに乗ってくれること」「あぁそうか!」「OSのファイルキャッシュに乗るということは、プロセスをまたいでもキャッシュが効くということで、これが大きい」「そうそう😋」「RailsのSQL キャッシュは基本的にアクション単位なのでアクションをまたぐと解放されてしまいますが、OSのファイルキャッシュはプロセスをまたいで効くのが強い」
参考: 1.8 SQLキャッシュ -- Rails のキャッシュ機構 - Railsガイド
「個人的にはproductionでのSQLiteでwarningを出すまでもないような気はしますけど、誤用を防ぐという意味では理解できます」「そうですね、理解したうえでSQLiteをproductionで使う人は自分でwarningをオフにできるでしょうし、それと誤用の可能性を秤にかけた結果この改修になったんでしょうね」「自分も本番でSQLiteを使うときは、よ〜く考えてからにしています」
SQLiteをRailsのproduction環境で使う主な問題は、
- これがデフォルトになっているので初心者が気づかないまま使ってしまう可能性があること
- SQLiteがディスクベースのデータベースでありながら、それを過渡的なクラウドベースの世界で使ってしまうこと
「自分のRailsアプリでは明確な意図を持ってSQLiteをproductionで使います」勢が多数派とは思えない。
#34715コメント(by DHH)より大意
🔗 has_one through:
にdisable_joins
オプションが追加
つっつきボイス:「マルチプルデータベース関連でこれとよく似た改修がこの間もありましたね(ウォッチ20210426): あのときはhas_namy through:
が対象だったかな」「今回はhas_one through:
でもdisable_joins
が使えるようになったんですね」
#41937で
has_many ... through:
が追加されたように、has_one ... through:
リレーションにdisable_joins
オプションを追加する。目的は、マルチプルデータベースのRailsアプリでテーブルが別のデータベースクラスタに置かれている場合にhas_one
リレーションシップを使えうようにすること。この場合、クラスタ間でのJOINは行えないのでJOINを回避する必要がある。
同PRより大意
🔗 PostgreSQLでtimestamp with time zoneをネイティブでサポート
つっつきボイス:「お、PostgreSQLでタイムゾーンありのタイムスタンプを使えるtimestamptz
が追加されたんですね」「デフォルトはタイムゾーンなしの方なのか」
- PostgreSQL:
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type
を導入
この設定は、マイグレーションやスキーマでdatetime
を呼び出す際に、Active Recordで使うネイティブ型を制御する。この設定は、設定済みのNATIVE_DATABASE_TYPES
のいずれかに対応するシンボルを受け取る。デフォルトは:timestamp
つまり、マイグレーションで、t.datetime
を使うと「timestamp without time zone」カラムが作成される。「timestamp with time zone」を使うには、イニシャライザで:timestamptz
に変更する。
これを変更した場合には、bin/rails db:migrate
を実行してschema.rbを再構築する必要がある。
Alex Ghiculescu
同Changelogより大意
「たしかに、これまではPostgreSQLのtimestampを使うとタイムゾーンなしになってたんですよ」「タイムゾーンありの方が好きかも」「timestamptz
という名前が微妙に長いけど、タイムゾーンのありなしを選べるようになったのはいいですね👍」
🔗 Active SupportのEnumerable#sum
とArray#sum
を非推奨化
- 元記事: Deprecates `Enumerable#sum` and `Array#sum` by alberto-mota · Pull Request #42080 · rails/rails
つっつきボイス:「Active SupportにあるEnumerable#sum
とArray#sum
が非推奨になったのね」「RubyネイティブのEnumerable#sum
とArray#sum
の方が断然高速なので今後はそちらを使って欲しいそうです」「お〜、Active Supportのメソッドが昇格してRuby本体に取り入れられることがときどきありますけど、これもそのパターンですね」「Rails側としては冥利に尽きますね🎉」
Ruby(2.4以降)にはパフォーマンスが著しく向上したネイティブの
sum
実装が含まれている。Rails 7.1からはEnumerable#sum
とArray#sum
を削除してRubyのネイティブ実装を使うことにする。
このコミットでは、適切な初期引数を持たない非数値引数の呼び出しに非推奨の警告を追加している。以下で議論しているとおり、RailsからActive Support版の機能が削除されたときにこれらの引数が必要になる。以下のような例でdeprecation warningが表示されるようになった。
%w[foo bar].sum
[[1, 2], [3, 4, 5]].sum
warningを回避するには以下のように呼び出す必要がある。
%w[foo bar].sum('')
[[1, 2], [3, 4, 5]].sum([])
Rails 7.1での非推奨化を準備するため、Rubyのネイティブ実装で
TypeError
になる[nil].sum == 0
についても非推奨化する。
同PRより大意
🔗Rails
🔗 Bootstrap 5がリリース
Happy Thursday—we just shipped v5.0.1 with some bugfixes and docs fixes. Thanks to the folks who shared feedback and helped resolve issues in this one! https://t.co/8NyGz81Y56
— Bootstrap (@getbootstrap) May 13, 2021
つっつきボイス:「そうそう、Bootstrap 5出ましたね」「IEサポートもついに終了」「今年の春学期に担当する大学の授業では検索のしやすさからBootstrap 4を使いますが、来年度やるならBootstrap 5でもいいかもですね」
「jQueryも必須でなくなったのはいい👍」「jQueryの目玉機能だった$("要素名")
みたいなセレクタも今やquerySelectorAll()
でできるようになりましたよね」「う、jQueryなしでできるようになってたとは知らなかった😅」「querySelectorAll()
は普通にどのメジャーなブラウザでも使えるはずですよ」
参考: Document.querySelectorAll() - Web API | MDN
参考: Can I use... Support tables for HTML5, CSS3, etc -- querySelectorAll()
「jQueryが当時画期的だったのは、$("")
を1個書くだけでCSSセレクタでDOM要素を簡単に選択できたこと」「あれは感動的なインターフェイスでしたね」「jQueryのeach()
的なメソッドも当時のブラウザでは標準で使えなかった」「現在のJavaScriptがそうしたものを標準として取り入れるようになったので、jQueryは役目を終えつつあるかなと感じますね」「今の人があの当時のJavaScriptを触ったらあまりに別物でびっくりするかも」
参考: .each()
| jQuery 1.9 日本語リファレンス | js STUDIO
🔗 Hanami 2.0.0 alpha2がリリース(Ruby Weeklyより)
📣 We’re delighted to announce the release of Hanami 2.0.0.alpha2, the culmination of two years of work and a revolutionary new vision for Hanami 2.0!https://t.co/4lmePh9hgB#hanamirb #ruby #opensource
🌸
— Hanami (@hanamirb) May 4, 2021
つっつきボイス:「おぉ、Hanamiの2.0.0が出そう」「コアを完全に書き直したそうです」「まったく新しいアプリをSinatraで書くぐらいならHanamiで書いてもいいかなという気持ちがありますね」「Hanamiのルーティングにroda gemを使うという提案がだいぶ前にあったのを思い出したんですが、結局ルーターもHanami独自のものを新たに作ったそうです」「ルーターはWebアプリで必ず通るところなので重要ですね: ここが重いと全体が重くなってしまうので」「たしかに」
🔗 RSpecのネスト
ネストの話というか、ふつーに「RSpecの理想的な書き方」の話っぽかった。内容に関しては僕もほぼ同意ですね〜。(基本的にsubject使わない派)
rspecのrspecに学ぶ、ネストの深いrspecを書かない方法 https://t.co/oNra7tInb1 #Qiita via @ytnk531
— Junichi Ito (伊藤淳一) (@jnchito) May 12, 2021
つっつきボイス:「RSpecはsubject
やlet
を使うかどうかみたいな議論になりがちなところがあるので、今はMinitestの方が好きです」「わかります」「RSpecだとネステッドなcontext
を書きすぎてしまうんですよね」
「RSpecで書かれたテストが複雑になりすぎると、RSpecのテストに対するテストが必要なんじゃないかとすら思えるときもあります」「RSpecで頑張って抽象度を高めるほどそうなりがちかも」「テストコードに不安を抱えるぐらいならMinitestでベタに書きたい派」「RSpecはテストをきれいに書きたくなるところがあるんですけど、本来やりたいのはアプリケーションコードが正しく動作していることを確認することだという気持ちが強まって、今はMinitestで書いてます」
参考: Rails テスティングガイド - Railsガイド
🔗 Rails UJSの舞台裏(Ruby Weeklyより)
つっつきボイス:「RailsのUJS(Unobtrusive JavaScript: 控えめなJavaScript)についてかなり詳しく解説しているようです」
参考: Rails で JavaScript を使用する - Railsガイド
「RailsでAjaxコードを書くようになるとUJSの理解が重要になってきますね: この記事のようにremote: true
から追いかけ始めて、data-method
属性のようなdata-
系属性をRailsで書けるのはなぜかを調べたりするようになりますよ」「ふむふむ」
# 同記事より
link_to "Example", "#", remote: true
=> "<a href='#' data-remote>Example</a>"
# 同記事より
Rails.handleMethod = (e) ->
link = this
# gets the method provided
method = link.getAttribute('data-method')
return unless method
...
参考: Rails学習者にrails-ujsの動作説明したら感動された話 - INODEVLOG
「rails-ujsのコードはそんなに大きくないはずですし、jQueryがRailsから外されたことで以前よりもシンプルになっていて読みやすいので、一度読んで見ることをおすすめします🎓」「お〜!」
前編は以上です。
バックナンバー(2021年度第1四半期)
週刊Railsウォッチ(20210511後編)AWS Lambda関数ハンドラをDSLで書けるyake gem、VPC Peeringが同一AZ転送量無料化ほか
- 20210510前編 属性メソッドをキャッシュして最適化、Railsのガバナンスに関する声明、bundle install高速化ほか
- 20210427後編 RactorでUDPサーバーを作る、JSONシリアライザalba gem、AppleのAirTagほか
- 20210420後編 ShopifyのJITコンパイラYJIT、PicoRuby、DynamoDBの3つの制約ほか
- 20210419前編 RailsのN+1クエリを定番以外の方法で修正する、GitLabのセキュリティ修正リリースほか
- 20210413後編 RubyMineのRBSサポートとCode With Me、GitHub ActionとDockerレイヤキャッシュほか
- 20210412前編 Active Record属性暗号化機能がRails 7にマージ、RailsNew.ioでrails newオプションを生成ほか
- 20210407後編 エイプリルフールのRuby構文プロポーザル、AWSのVPC Reachability Analyzerほか
- 20210406前編 GitHubが修正したRailsセッションハンドリングの競合、erb/haml/slimの速度比較ほか
- 20210330後編 Active Recordモデル属性暗号化が標準で入る可能性、Flipper Cloud、awesome_printほか
- 20210329前編 特集: Rails更新版の臨時リリースとmimemagic gemのGPL問題
- 20210323後編 GitHub Actionsで使えるruby/setup-ruby、中高生国際Rubyプログラミングコンテスト2020ほか
- 20210322前編 Active Recordのstrict loadingの修正、セキュリティリリースのポリシー追加、N+1チェッカーprosopite gemほか
- 20210316後編 testdouble/standard gem、DockerfileベストプラクティスとDockerfileのlintツールhadolintほか
- 20210315前編 Active Recordのenum関連改修、Active SupportのEnumerableでpluckが使えるほか
- 20210309後編 RubyのIRBに隠れているイースターエッグ、Power Automate Desktop、SQLクエリのありがちなミス6つほか
- 20210303後編 Bundlerのセキュリティ修正、Rubyのガベージコレクション記事、Rubyが2/24に誕生日ほか
- 20210222 ActiveRecord::Relationの新メソッドload_asyncとexcluding、Active Jobのperform_laterの改善ほか
- 20210209後編 Rubyでミニ言語処理系を作る、Kernel#getsの意外な機能、CSSのcontent-visibilityほか
- 20210208前編 Rails次期リリースがバージョン7に決定、thoughtbotのアプリケーションセキュリティガイドほか](/hachi8833/2021_02_08/103801)
- 20210202後編 Ruby 3 irbのmeasureコマンド、テストを関数型言語のマインドセットで考えるほか
- 20210201前編 Webpackerのガイドがマージ、RailsはRuby 3でどのぐらい速くなったかほか
- 20210126後編 Google Cloud FunctionsがRubyをサポート、Ruby 3のパターンマッチングでポーカーゲームほか
- 20210125前編 Railsリポジトリのデフォルトブランチがmainに変更、Rails 6.1はMySQLのENUM型に対応済みほか
- 20210120後編 Ruby 3.0の新機能で遊ぶ、RubyスニペットをJSに変換するRuby2JS、rspec-parameterized gemほか
- 20210113後編 Ruby 3.0 Ractor解説記事、Vercelホスティングサービス、教育用OS xv6ほか
- 20210112前編 Active Recordの範囲指定バリデーション改善、soleとfind_sole_byメソッド、AlgoliaとRailsほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)