- Ruby / Rails関連
週刊Railsウォッチ: Kaigi on Rails 2022がCFP公開、Discordの公式Railsサーバーが一般公開ほか(20220627前編)
こんにちは、hachi8833です。今日の暑さはヤバいですね。
【気象予報士解説】「過去100年で最も高い気温」レベルか #nhk_news https://t.co/6Solww1IBU
— NHKニュース (@nhk_news) June 25, 2022
🔗Rails: 先週の改修(Rails公式ニュースより)
今回のChangelogは少なめでした。
🔗 MessageVerifier
のイニシャライザにurlsafe
オプションが追加
- PR: Add urlsafe option to MessageVerifier initializer by shouichi · Pull Request #45419 · rails/rails
ActiveSupport::MessageVerifier.new
がオプショナルのurlsafe
を受け取るようになった。urlsafe: true
を渡すとurlsafeな文字列を生成する。
verifier = ActiveSupport::MessageVerifier.new(urlsafe: true)
message = verifier.generate(data) # => "urlsafe_string"
後方互換性のため、デフォルトでは
false
になる。
Shouichi Kamiya
同PRより
参考: Rails API ActiveSupport::MessageVerifier
つっつきボイス:「MessageVerifier
って何だろう?」「ぐぐったらこの記事が出てきた↓」「直接使うことはあんまりない感じでしょうか?」「Active Supportで公開されているので使ってもいいと思いますけど、意識して使ったことはなかったかも」
参考: RailsのMessageVerifierの内部実装を追ってみた - Qiita
RailsではMessageVerifierをCookieで改ざんのチェックに利用していて、署名をつけたメッセージを作成と、メッセージの署名を検証するのに利用されています。
他にはパスワード再発行メールでのトークンなどにも使われているそうです。
同記事より
「改修の方は、これまでMessageVerifier
で使われていたBase64.strict_encode6
だと生成文字列がurlsafeにならないのでBase64.urlsafe_encode64
に切り替えた、なるほど」
# activesupport/lib/active_support/message_verifier.rb#L211
private
def encode(data)
- ::Base64.strict_encode64(data)
+ @urlsafe ? Base64.urlsafe_encode64(data) : Base64.strict_encode64(data)
end
def decode(data)
- ::Base64.strict_decode64(data)
+ @urlsafe ? Base64.urlsafe_decode64(data) : Base64.strict_decode64(data)
end
参考: module Base64
(Ruby 3.1 リファレンスマニュアル)
「後追いの修正プルリクもマージされていました↓」「そういえばBase64エンコードした文字列の空きは=
で埋めたりしますけど、それをオフにしたんですね」
- PR: Fix urlsafe MessageVerifier not to include padding by shouichi · Pull Request #45424 · rails/rails
# activesupport/lib/active_support/message_verifier.rb#L213
def encode(data)
- @urlsafe ? Base64.urlsafe_encode64(data) : Base64.strict_encode64(data)
+ @urlsafe ? Base64.urlsafe_encode64(data, padding: false) : Base64.strict_encode64(data)
end
🔗 Active Storageのattach
メソッドをAttached::One
についても修正
#45345で行われたコード変更の後で、
ActiveStorage::Attached::One
にもActiveStorage::Attached::Many#attach
と非常によく似たattach
メソッドがあることに気づいた。単なるリファクタリングではなく、いくつかのブランチで戻り値が変更されたことを考えると、こちらも統一する方がよさそう。
より
つっつきボイス:「#45345は、先週のウォッチで見た#41661のトランザクション内のattach
複数回実行と関連していそう(ウォッチ20220613)」「#41661に続いて#45345でActiveStorage::Attached::Many#attach
を修正して、一貫性のためにActiveStorage::Attached::One
も同じように修正したということみたいですね」「ややこしい」
参考: Fix #41661 attaching multiple times within transaction by santib · Pull Request #42300 · rails/rails
参考: Fix #45339 attachments for new record within transaction by santib · Pull Request #45345 · rails/rails
🔗 mini_magickをブロックの外でrequire
するよう修正
- PR: require mini_magick at the level it is being used by joelcogen · Pull Request #45420 · rails/rails
discussのrubyonrails-coreを参照。
require "mini_magick"
は、download_blob_to_tempfile
に渡されるブロック内で呼び出されるが、30行目ではブロックの外で使われている↓。
rescue MiniMagick::Error => error
MiniMagick::Error
はブロックの外で定義する必要があり、さもないとdownload_blob_to_tempfile
が失敗したときにNameError
が発生する。しかもこのブロックは決してyield
されないので、mini_magickも決してrequire
されない。
自分はこれを実稼働中のアプリで目撃した。ファイルがS3から削除されたためにdownload_blob_to_tempfile
が失敗したが、ブロックがまったくyield
されなかった。mini_magickはそれまでrequire
されていないのでMiniMagick::Error
が定義されず、現在のエラーが伝搬されずにNameError
が発生する。
同PRより
つっつきボイス:「Active Storageのmini_magick関連の修正」「mini_magickをブロック内でrequire
してたけど、それを使うエラー処理がブロックの外にあったので意味がなかった、たしかに」
# activestorage/lib/active_storage/analyzer/image_analyzer/image_magick.rb#L11
private
def read_image
- download_blob_to_tempfile do |file|
+ begin
require "mini_magick"
+ rescue LoadError
+ logger.info "Skipping image analysis because the mini_magick gem isn't installed"
+ return {}
+ end
+ download_blob_to_tempfile do |file|
image = instrument("mini_magick") do
MiniMagick::Image.new(file.path)
end
if image.valid?
yield image
else
logger.info "Skipping image analysis because ImageMagick doesn't support the file"
{}
end
+ rescue MiniMagick::Error => error
+ logger.error "Skipping image analysis due to an ImageMagick error: #{error.message}"
+ {}
end
- rescue LoadError
- logger.info "Skipping image analysis because the mini_magick gem isn't installed"
- {}
- rescue MiniMagick::Error => error
- logger.error "Skipping image analysis due to an ImageMagick error: #{error.message}"
- {}
end
🔗Rails
🔗 Discordの公式Railsサーバーが一般公開(Rails公式ニュースより)
We are opening to the public an official Rails Discord server. Come to talk about how to contribute to the framework and its related libraries https://t.co/3o30yOCujK
— Ruby on Rails (@rails) June 16, 2022
つっつきボイス:「少し前にRailsリポジトリで古いプルリクの自動削除をやめてRails issuesチームが新たに創設されていましたね(ウォッチ20220523)」「その続きとして、Discordで公式Railsサーバーを一般公開したそうです↓」「最近こういうのにDiscordをすごくよく使うようになってきた印象がありますね」
参考: discord.com/invite: Ruby on Rails
Discordアプリがなくてもブラウザであっさり参加できました。generalチャンネルで最も古い書き込みは2022/05/19なので、新たに作ったようです。
参考: Discord | 会話や交流が楽しめるプラットフォーム
「既存のRuby on Rails Discussionsも引き続きサポートに使うそうです↓」
参考: Latest rubyonrails-talk topics - Ruby on Rails Discussions
🔗 RSpecで引数に特定の値が渡された時だけスタブする
つっつきボイス:「引数が特定の値のときだけスタブする方法ですか」「allow(shop).to receive(:sell).and_call_original
を書いてから次のallow(shop).to receive(:sell).with('banana').and_return(nil)
を書かないといけない: 自分はあまりこういう書き方はしないけど、たしかに可能ですね」
# 同記事より
describe 'Shopper#buy_fruits' do
let(:shop) { Shop.new }
before do
allow(shop).to receive(:sell).and_call_original
allow(shop).to receive(:sell).with('banana').and_return(nil)
end
it do
shopper = Shopper.new
expect(shopper.buy_fruits(shop)).to eq ['apple', nil, 'orange']
end
end
「ただ、この書き方を使い始めるとスタブメソッドの呼び方次第でうまくいったりいかなかったりすることがあるので、正しく動作しているかどうかを確認するのが少し面倒になるかな」「なるほど」
🔗 Kaigi on Rails 2022が10月にオンライン開催、CFPを公開
/#kaigionrails
CFP募集中!!
\
Kaigi on Railsでお話してみませんか?
初心者・中級者・上級者、あなたにしかできないトークがあるはず✨
締め切りは7月31日(日)です!
たくさんのご応募お待ちしております🙌https://t.co/dXK7vTguy5— Kaigi on Rails (@kaigionrails) June 21, 2022
つっつきボイス:「お、Kaigi on Rails 2022🎉」「10/21〜10/22なので、9月のRubyKaigi 2022の翌月ですね」
参考: Kaigi on Rails 2021
参考: Kaigi on Rails
「Kaigi on Rails 2022はオンラインのみだそうです」「日本はまだ現地開催があまり復活していない感じですけど、主催側の負担が大きくなりますし、悩ましいところでしょうね」「そうなんですよね...」
🔗 Webアプリで忘れがちなセキュリティ対応5つ(RubyFlowより)
つっつきボイス:「ベストプラクティスというより、思いついた順のメモ書きっぽい記事かな」「少しとりとめもない感じですね」
「このサイトでセキュリティヘッダーをチェックできるそうです↓」「Railsデフォルトのセキュリティヘッダーのままだと、こういうサイトでたまに警告が出たりしますね」「そういえばGitHub公式のsecure_headersというgemもありますね」
参考: Analyse your HTTP response headers
「メールのセキュリティは、SPFやDKIMやDMARCをチェックすべきという定番の話」「これもチェックサイトがあるんですね↓」
参考: インターネット用語1分解説~SPFとは~ - JPNIC
参考: インターネット用語1分解説~DKIMとは~ - JPNIC
参考: インターネット用語1分解説~DMARCとは~ - JPNIC
参考: SPF record Checker | SPF record Tester - Mimecast | DMARC Analyzer
参考: DKIM record Checker | Test your DKIM record - DMARC Analyzer
参考: DMARC record Checker | DMARC record Tester - Mimecast | DMARC Analyzer
「ファイル転送のセキュリティ: たとえばこちらで制御できないサードパーティのサーバーを経由するとファイルが残ってしまう可能性があるので、どこまでセキュアに転送すべきかという問題は常に悩ましい」「永遠の課題ですね」
「magic-wormholeはエンドツーエンドのファイル転送ツールか: 似たようなツールは他にもあると思いますが、こういうのを使いたい場合があるのはわかる」
「最後はAWSのIAMポリシーの話」「IAMポリシーで本当に必要な権限だけを付与しようとすると、いくらでも手間がかかる、かといって楽に済ませようとするとセキュリティが粗くなってしまう」「そこですよね」「AWS公式のチュートリアルもそこまで厳密ではありませんし」
参考: IAM でのポリシーとアクセス許可 - AWS Identity and Access Management
参考: IAM のチュートリアル - AWS Identity and Access Management
「IAMポリシーは、S3のような比較的シンプルなものでも、たとえばリストアクセスを許可しないとライブラリが動かなかったりするんですよ: ListAllMyBuckets
を許可しないとバケットの存在をチェックできないとか」「あ〜」「IAMポリシーは知らないとわからないものも多いし、挙動が期待と違うことも割とあります」「う〜む」「今は特定用途のIAMポリシーについてはベストプラクティスも出てきているので、そういうのを使うしかないのかもしれないという気持ちです」
「あとIAMポリシーで大事なのは、AWSアカウントベースで分割しておくことでしょうね: 記事のこの設定↓のように"Resource"
ベースでやると後々手間がすごいことになる」「なるほど」
# 同記事より
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
「たとえば上のポリシーの"Resource"
は、下はyour-bucket-name/*
のように/*
を付けないといけないのに、上のリストバケットに/*
を付けたら動かない、というふうに知らないとわからない細かい違いが多いんですよ」「/*
のあるなしを指定するために同じことを2回も書かないといけないとは...」
前編は以上です。
バックナンバー(2022年度第2四半期)
週刊Railsウォッチ: VSCodeでRubyコード実行結果を表示、rubygems.orgがgem作者に多要素認証を呼びかけほか(20220621後編)
- 20220620前編 GitLabがRailsにこだわる理由、Rails7アップグレードのハマりどころほか
- 20220614後編 Rubyの実行モデル解説記事、shale gem、HTTP/3がRFC 9114にほか
- 20220613前編 Hotwireをアプリ構築で学ぶ、Active RecordのDurationとPostgreSQL intervalデータ型ほか
- 20220607後編 Shopifyのlanguage server ruby-lsp、PostgreSQL 15 Beta 1リリースほか
- 20220606前編 BasecampのHotwireページネーション、Query Object、Lograge gemほか
- 20220531 Railsコミュニティアンケート結果発表、書籍『Sustainable Web Development with Ruby on Rails』ほか
- 20220524後編 Railsコアチームとコミッターに新メンバー、ruby-buildでのRust YJITサポートほか
- 20220523前編 Hotwireの用途解説記事、RubyKaigi 2022プロポーザル募集開始ほか
- 20220517後編 rubygemsに「scoped gems」の提案、RSpecのブロック構文ほか
- 20220516前編 Active Modelで属性のパターンマッチをサポート、猫でもわかるHotwire入門ほか
- 20220511後編 Ruby 3.2.0devにRust版YJITがマージ、Docker Compose V2ほか
- 20220510前編 Active RecordにPromiseと非同期集計メソッドがマージ、climate_control gemほか
- 20220419後編 RubyのGCコンパクション改修、jemalloc、ReDoSの自動検出修正ほか
- 20220418前編 RailsConf 2022が5月17〜19日開催、認可機能解説記事ほか
- 20220412後編 HashieでRubyのハッシュを強化、最近のRubyコア解説記事ほ
- 20220411前編 Turbo Railsチュートリアル、Active Recordの「Leaky Abstraction」を削減ほか
- 20220406後編 RBS関連記事、Ruby formatterプロジェクト、Google Cloud Runほか
- 20220404前編 Ruby 3.2.0 Preview 1リリース、Rails向けDocker環境ジェネレータ、scientist gemほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)