週刊Railsウォッチ(20181210)update_columnは要注意、DBカラムコメントは書こう、個人情報扱いの注意点、Capistranoはやっぱりいいほか

こんにちは、hachi8833です。今年最後の公開つっつき会も盛況でした。ご参加いただいた皆さまありがとうございました!🙇 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください ⚓臨時ニュース: Ruby 2.6.0-rc1がリリース(Ruby公式ニュースより) Ruby 2.6.0-rc1 released https://t.co/c9qLnLZg8D だいたいRuby 2.6の機能は出揃ったはずなので、そろそろ試していただけるとありがたく思います — 成瀬 (@nalsh) December 6, 2018 プレスリリース: Ruby 2.6.0-rc1 Released 公開つっつき会の翌日のリリースでした。詳しくは上をご覧ください。 その後jnchitoさんの懇切丁寧なまとめ記事も出ました↓。 今年も書きました。Ruby 2.6のまとめ記事です!個人的にはProc#>>が好き〜❤️サンプルコードでわかる!Ruby 2.6の主な新機能と変更点 https://t.co/P8cXY4ZBgK — Junichi Ito (伊藤淳一) (@jnchito) December 9, 2018 ⚓Rails: 先週の改修(Rails公式ニュースより) ⚓Rails 5.2.2がリリース 元記事: Rails 5.2.2 has been released! | Riding Rails GitHub Releases: Release 5.2.2 · rails/rails 今回社内のSlackで話題になったのは、GitHub上のreleases/tagの方がリリースノートがまとまっていて読みやすくなっていたという点でした。 つっつきボイス:「セキュリティ修正なのかな?」「今度のは普通のバグ修正のようです」「Rails 5.2.2リリースを少し詳しく見たいというリクエストをいただきましたので、他の項目は軽めで今回はここを中心に見ていく感じにしたいと思います😊」「単なるfix bugはさっと流していく感じで☺️」 ⚓エスケープ復元のバグ Fix bug where URI.unescape would fail with mixed Unicode/escaped character input: 「URI.unescapeのバグか↓」「バの濁点が分離してるのかな?」「いや、これはエスケープの種類(8進数形式とURL形式)が複数混じっているときにコケるバグ」「あーそっちですね」「そもそも混ぜるな危険☠️」 URI.unescape(“\xe3\x83\x90”) # => “バ” URI.unescape(“%E3%83%90”) # => “バ” URI.unescape(“\xe3\x83\x90%E3%83%90″) # => Encoding::CompatibilityError ⚓Active Recordの#update*系メソッドは要注意 Allow aliased attributes to be used in #update_columns and #update. 「#update_columnや#updateでエイリアスの属性を使えるようにしたと」 「ところでActive Recordの#update_columnといえば、良心的なRailsエンジニアなら普通は使わないメソッドで有名ですね😎」「ムフフ😎」「ムフフ😎」「基本、使うもんじゃない」「使ってないですー」 「今日使いました😇」「おっと😆それは普通ならrejectされるか、さもなければNEEDFIXとか書かれるヤツです☺️」「自分も知らなかった💦」「今日でよかった☺️」 「#update_columnメソッドがよろしくない理由ですが、昔のこの記事↓をちょっと開いてみてください(古い情報です)」 参考: » Railsのコールバックまとめ TECHSCORE BLOG 以下は同記事に記載されている時点のupdate_*系メソッドをざっくり分類したものです。 コールバックを実行する updateupdate_attributeupdate_attributesupdate_attributes! コールバックを実行しない update_columnupdate_allupdate_counters 「Active Recordでデータベースを更新するメソッドを大きく分けるとsaveとupdateになるんですが、基本的にsaveを使うべき」「#updateはSQLのUPDATE文を発行するんですが、上のようにupdate系にはコールバック(フック)が動かないものがあります: この記事の時点の記述によれば、updateはコールバックを実行するのにupdate_columnはコールバックを実行しない」「マジで?😅」「一貫性が見えない…」「これがとてもわかりにくいので、#update_columnや#updateは基本使わない方がいい」 なお、Active Recordのコールバックでは以下のまとめ記事が有名ですが、その後#25503でupdate_attributeの挙動が修正されたりしているのでご注意ください。 参考: ActiveRecord の attribute 更新方法まとめ - Qiita 「コールバックが呼ばれないと何が起きるかという話もついでにしちゃいましょう: コールバックが呼ばれないと、before_*フックやafter_*フックと連動している処理が全部スキップされてしまいます」「😱」「そうすると、Railsのモデルの中で期待されている制約に違反するデータができてしまう可能性がある」 「そうした制約はRDBMSの側でCONSTRAINTとか使ってかけるべきという考え方“も”あるんですが、Railsではそうしたバリデーションなどは原則としてRubyのコードで行うという文化になっていますね」「あーそうなのか: 自分は両方でやるものかと思ってた」「そこはプロジェクトのポリシーにもよるので、絶対というものではありませんね☺️」 「実際そのあたりの棲み分けって悩ましくて、非常にシンプルなCONSTRAINTだったらRDBMS側でやってもいいんですけど、ビジネスロジックに属する制約をモデルから離れたRDBMSに置くのはちょっとねー、という思いもあるわけです」「おー」「RDBMS側に置いているビジネスロジックが複雑になってきたら、そのうちストアドプロシージャになってしまうんじゃないかと😆」「😆」 参考: ストアドプロシージャ - Wikipedia 「補足すると、ここで言っているRDBMSのCONSTRAINTというものは、NOT NULLなんかと同じような類の制約です: Railsから開発の道に入った人だとこの辺は普段あまり意識しないかもしれませんが」「まだNOT NULLしか使ったことなかった🤭」「RDBMSにはこうしたCONSTRAINTなどの機能が元々あるんですよ😚」 「それが実際のRailsアプリになると、だんだん単純な制約に収まらなくなってきて、たとえばカラムAがこういう状態のときはカラムBは何件以上なければならない、みたいな複雑な制約になるとCONSTRAINTだけでは表しきれないので、あくまでRDBMSでやろうとすると上述のストアドプロシージャを使うことになると」「ふーむ」「ストアドプロシージャの向こうには闇が広がってますから🌘」「😆」 「ストアドプロシージャは、要するにRDBMSの中でプログラム(関数)を書いて実行できるようにする仕組み: ただし、いわゆる手続き型言語のプログラムとはちょっと趣が違う、特徴的な書き方をします」「PL/SQLはOracleのだったかな?」「そうですね」「とにかくストアドプロシージャはRDBMSごとに違う」「つまり互換性がない😇」 参考: PL/SQL - Wikipedia 「ストアドプロシージャで制約をかけていれば、仮にさっきの#update_columnメソッドを使ったとしてもRDBMS側でfailするので間違って更新されることはありませんけどね😆」「😆」 「まあそういうわけで、#update_columnは基本使わないこと: 使うなら#update_attributesにしましょう😍」 参考: ActiveRecord::Persistence 「実はattributeの呼び出しを1回にまとめようと思って#update_columnを使いました😅」「おっと〜、それは一番残念なパターン😆」「😆」「あ、そういえばその書き方、Railsチュートリアルに載ってますよ🤓」「ありゃ~😆」「それはアカンな〜😅」「後で探しときます: それは原作者にフィードバックしないと📩」 念のため、現時点の英語版↓で確認しました。 参考: Chapter 11: Account activation | Ruby on Rails Tutorial (Rails 5) | Softcover.io 追いかけボイス: 「このコードにはバリデーションがないので辛うじて直接の問題にはなっていませんが、チュートリアルとしては一言注意が必要ですね⚠️」 # 英語版Railsチュートリアル11章の演習より class User < ApplicationRecord attr_accessor :remember_token, :activation_token before_save … Continue reading 週刊Railsウォッチ(20181210)update_columnは要注意、DBカラムコメントは書こう、個人情報扱いの注意点、Capistranoはやっぱりいいほか