2022.10.28プライベート明けましておめでとうございますshimo新年ですね。年末タイに来て、現在はバンコクで働いておりまして、今週末日本に帰る予定です。バンコクに着いたのは明け方前で、タクシーで久しぶりにボラレてしまいました。集中力が欠けてる深夜こそ気を抜いてはいけないなあと思った次第です。Contents昨年を振り返って今年の意気込み本題(といいつつもちょっと小ネタ)find_byメソッドの引数が。RailsでのWebアプリケーション、API開発、そして少しAndroidアプリ開発に携わった。C、C++、C#などでミドルウェアを開発してきた生粋のエンプラ人間だった私だったが、だいぶWeb人間に変わってきた気がする。いい意味で変わったのならいいのだが。会社のメンバーも増えてきた。弊社は基本的に完全リモートワークであるので、メンバーが増えてきた場合にどうなるのかいろいろ楽しみである。やり方を変えていかないといけないと思うが、そういった変化を楽しみながら柔軟にやっていきたいと考えている。これは個人的な話だが、先月に趣味で作った初のiOSアプリをAppleに申請した。アプリへのデータ配信用APIサーバはRailsでアプリを作ってDigitalOceanを使って立てた。DigitalOceanはRailsアプリのファイルをコピーするだけですぐにサービスを動かせるし安いので、時と場合によっては非常に便利である。大変に見た目がしょぼい(機能は素晴らしいと思っている)アプリなのだが、とりあえず審査に出してみて反応を見ようと思って出したところ、瞬殺リジェクトされてしまった。冬休みに修正版を出したので、私個人の初iOSアプリがリリースされるのが楽しみな今日この頃である。Railsのスキルを伸ばしつつ、フルスタックエンジニアを目指すべく?????積極的にスマートフォンやWebクライアントサイドの開発にも関わっていきたいと思っている。他にも、前職でやってきたJavaや.NETは一応得意分野であるので、そこらへんの受託案件をいただけばぜひ全力で取り組みたいと考えている。本題(といいつつもちょっと小ネタ)さて本題であるが、新年っぽくない地味なネタとなってしまうが、RailsのActiveRecordで最近ちょっとハマった小粒ネタを2つ書こうと思う。Rails、MySQLのバージョンは以下。5.6.17find_byメソッドの引数が。最近作りこんだバグのお話。ActiveRecordのfind_byメソッドに主キーを渡してモデルを検索しようとした際、本来ハッシュを渡すべきところで、誤って主キーの値のみを渡していたコードがあった。"hoge">非常に単純なバグなのだが、、、テストコードで検出できず、発見が遅れた。2)がid:2のレコードを返しているのに対し、find_by(2)はエラーとはならず、id:1のレコードを返している。1これは当然ながら意図したクエリではない。エラーとならずに結果が返ってくる。1で一番最初のレコードが返ってくる。エラーにならずに結果がちゃんと1件返ってくるというのがちょっといやらしくて、テストコードは通ってしまっていた。いうのも、テストコードではオブジェクト(レコード)をひとつしか作っておらず、find_byメソッドに誤った引数を与えていても意図せずに正しいレコードが引けてしまっていたためである。テストコード以前に、ちゃんと動かして気付かない私が悪いという話であるのだが。find_byメソッドでなくfindメソッドは、主キーのみを渡して検索する。ハッシュは受け付けないので、これは間違えることはないだろう。4.2ではfind_byの実装はだいぶ変わっているようだが、この件に関しては同様のようである。いうわけで、そんなん間違えねえよ!っていう声が聞こえてきそうですね。なんかバグを作りこんだ言い訳をしてるようで恐縮なのですが、find_byに渡す引数にはちょっと気をつけようというお話でした。ネストしたモデルの属性更新時にユニーク制約でハマった問題ActiveRecord関連でもう一つちょっと困ったネタ。こんなモデルがあった場合。:name」を書いてあっても、DBにユニーク制約を入れていない場合、以下のように一度に同じ名前を登録することができてしまう。taken"]つまり、'validates_uniqueness_of'をつけていてもchildren_attributesで一度に同じ値に更新された場合にはバリデーションは効かない。これはaccepts_nested_attributes_forに限った話ではなく、validates_uniqueness_of一般に言える話である。true調べてみると、同じように困っている人がRailsのissueでたくさん見つかった。(上記2つのサンプルコードは、このissueから流用した。)https://github.com/rails/rails/issues/4568そして問題を解決するというPRもあるのだが、最終的にマージはされていない。結局、複数ユーザからの更新などを考えると、DB側にユニーク制約を入れる必要がある。どこまでRails側で救うかという話で、今回の場合、複雑なコードを入れ込む割には、根本的な解決にはならないため、Rails側には入れたくないということのようである。Errorでいいやというニーズはけっこうあるのではと思う。何か勘違いなどしていたらごめんなさい。結局、以下のような対応をした。メモリ上でユニークかをチェックするようにした。endend以上、まとまりのない話になってしまいましたが、本年もどうぞよろしくお願い申し上げます。upINDEX昨年を振り返って今年の意気込み本題(といいつつもちょっと小ネタ)find_byメソッドの引数が。ウェブサービス株式会社(DWS)公式ブログ記事URLをコピーしました。