Rails

Railsにて、1つのテーブルの複数列で同じテーブルを参照し、参照先を主キーもしくは主キー以外の属性としたい場合に、モデルやマイグレーションの定義方法を調べてみた

Railsを使っている中で、記事のタイトルのようなことがしたくなりました。 例えば、以下のようなことがしたくなりました。 applesとcolorsという2テーブルがある applesテーブルには以下の3列があり、いずれもcolorsと関連を持たせたい 列について 果実の色 …

Railsにて、トランザクションの中だとモデルのid列はいつ設定されるのか確認してみた

Railsを使っている中で、「トランザクションの中だとモデルのid列はいつ設定されるのか」が気になったことから、確認してみたときのメモを残します。 目次 環境 動作確認 余談:Railsのバージョンにより、トランザクション内での return 等の挙動が変わる ソ…

Railsにて、ActiveSupport::TaggedLoggingやActiveSupport::ErrorReporterを使って、Request-IDをログへ出力してみた

Railsをproductionモードで動かしている時、ログに I, [*** #237177] INFO -- : [95c95a65-608b-45d3-aa02-bcf61950e7c2] Completed 204 No Content in 1ms と、 [95c95a65-608b-45d3-aa02-bcf61950e7c2] のようなHTTPリクエストを識別できるようなタグがつ…

rspec-parameterizedにて、factory_botのtraitを動的に指定する

以前、factory_botの traitを使ったことがありました。 Rails + factory_botで、sub factoryやtrait・callbackを使って関連データを生成してみた - メモ的な思考的な そんな中、 rspec-parameterized を使ってテストを書くときに、動的に trait を指定してデ…

rspec-parameterizedで、letやlet!定義された変数の値を上書きする

gem rspec-parameterized は、RSpecでパラメタライズドテストを書くときに便利です。 https://github.com/tomykaira/rspec-parameterized 最近だと、 table syntaxを使っていない場合は rspec-parameterized-core を使うことで native extensionへの依存をな…

各RailsアプリにOpenTelemetryを組み込み、収集したデータをJaegerで表示してみた

最近「オブザーバビリティ(Observability)」が気になっていたので、オライリーの「オブザーバビリティ・エンジニアリング」を読みました。 O'Reilly Japan - オブザーバビリティ・エンジニアリング その本の7章ではOpenTelemetryが紹介されていました。 Open…

Railsで、included付のConcernをincludeしたり、prepended付のConcernをprependしてみた

Railsには Concern と呼ばれる関心事を分離する機能があります。 我々はConcernsとどう向き合うか - おもしろwebサービス開発日記 そのConcernをモデルに組み込もうとした時、 モデルで include するか prepend するか Rails API: ActiveSupport::ConcernとM…

Rails + RSpecで、引数が必要なRake Taskのテストコードを書いてみた

Rails + RSpecにて、Rake Taskのテストコードを書く機会がありました。 ただ、引数が必要なRake Taskのテストを書くときに悩んだことがあったため、メモを残します。 目次 環境 引数なしのRake Taskをテストする 引数ありのRake Taskをテストする [] を使っ…

ActiveSupportのdeep_mergeに対し、with_indifferent_accessと組み合わせたり、blockを渡してみたりしてみた

Rubyでは Hash#merge を使うことで、2つのハッシュをマージできます。 Hash#merge (Ruby 3.2 リファレンスマニュアル) 2つのハッシュでキーが異なる場合は、それぞれのキーを持つハッシュへとマージされます。 h1 = { name: 'foo' } h2 = { color: 'red' } h…

Rails + RSpecにて、changeマッチャまわりをいろいろ試してみた

前回に続き、RSpecのchangeマッチャに関する記事です。 値の変化を検証する時は change マッチャが便利です。 ただ、「こんな時どうするんだっけ」と調べることが多かったことから、 change マッチャまわりをいろいろ試してみたときのメモを残します。 目次 …

RSpec 3.12 + rspec-rails 6.0.2にて、change + have_attributesマッチャを使うとエラーになるため、回避策を試してみた

RSpecの change マッチャを使うと、処理前後における値の変化を検証できます。 https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/change/ 例えば # == Schema Information # # Table name: favorites # # id :integer not null, prim…

Rails + ActiveSupport::InheritableOptionsを使って、既存のハッシュをドットアクセスできるようにする

ハッシュに対してドットアクセスできる機能を追加しようと調べたところ、Rubyの標準ライブラリに OpenStruct がありました。 ためしに使ってみたところ、以下のようになりました。 require 'ostruct' o = OpenStruct.new({foo: 'bar'}) puts o.foo #=> bar …

Rails7.0系で、キャッシュストアとセッションストアをRedisにしてみた

以前、Railsのキャッシュストアとセッションストアとして memcached を使ったことがありました。 Rails6.1で、セッションをキャッシュとは別のmemcachedへ保存する - メモ的な思考的な そんな中、Redisを使って試してみたことから、メモを残します。 目次 環…

RailsのActiveRecordで、joinsメソッドやwhereメソッドで、ハッシュで条件を指定する

RailsのActiveRecordにて、SQLのJOIN句やWHERE句の条件を記載する場合、 JOIN句 joins() や eager_load() などのメソッド 13 テーブルを結合する | Active Record クエリインターフェイス - Railsガイド WHERE句 where() メソッド 3. 条件 | Active Record …

Rails + factory_botで、sub factoryやtrait・callbackを使って関連データを生成してみた

Rails + RSpec + factory_bot にて、あるモデルの関連データを生成する方法を調べたところ、factory_botのGETTING_STARTEDにいろいろな方法が記載されていました。 https://github.com/thoughtbot/factory_bot/blob/main/GETTING_STARTED.md そこで、GETTING…

Railsで、二重否定(!!) + ぼっち演算子(&.) が使われているソースコードの挙動を確認してみた

Railsを使ったソースコードを眺めていたところ、モデルのメソッドにて def foo !!bar&.baz end というコードがありました。 どのような挙動になるのか気になったので、試してみた時のメモを残します。 目次 環境 モデル構造 挙動確認 否定(!)や二重否定(!!)…

Railsで、DBから取得するデータに対し、order・sort_by・sortを使って、昇順・降順ソートする

RailsでActiveRecordを使ってDBからレコードを取得するときに、以下を考慮した昇順・降順ソートで迷ったことがあったため、メモを残します。 取得するタイミング データ取得時 (SQL発行時にソート) データ取得後 (Rubyのarrayになってからソート) ソートキー…

RailsのActiveRecordで、ある条件の関連先レコードがない場合にその関連元データを取得する

以前、RailsのActiveRecordにて、 eager_load を使って 子側が存在しない場合は結果に含めずに抽出する 子側が存在しなくても、結果に含めて抽出する をしました。 Railsで、eager_loadのLEFT OUTER JOINにて、WHERE句とON句のそれぞれで絞り込みしてみた - …

Railsにて、モデルのカスタムバリデーションメソッドの中で、標準のエラーメッセージを利用する

Railsでは、標準で用意されているモデルのバリデーションの他に、カスタムバリデーションメソッドを作成することで、独自のバリデーションを行えます。 6 カスタムバリデーションを実行する | Active Record バリデーション - Railsガイド そんな中、「カス…

Railsにて、同じ値でデータ更新した場合、タイムスタンプカラム(updated_at)が更新されない

Railsにはタイムスタンプカラム( created_at / updated_at )があり、各カラムは データ作成時 created_at と updated_at が設定される データ更新時 updated_at が更新される という挙動になります。 2.2 スキーマのルール | Active Record の基礎 - Railsガ…

Pundit + Rolify を使って、Rails製APIアプリでロールによる認可制御を行ってみた

Rails + ロールでの認可制御を調べたところ、以下のページに認可制御のgemがまとまっていました。 Category: User Authorization - The Ruby Toolbox まずは一番Githubのstarが多いgemからみてみようということで、 Pundit をさわってみることにしました。 v…

Rails + React + OpenAPI な環境で、クエリパラメータに配列を指定する時に調べたことをまとめてみた

Rails + React + OpenAPI な環境で、クエリパラメータに配列を指定することがありました。 ただ、実装するまでにいろいろ調べたことがあったため、メモを残します。 目次 環境 わかったこと Railsでは ids[]=1&ids[]=2 な書式のクエリパラメータを受け取れる…

Rails + Active Job + Delayed::Jobにて、ジョブを作ってみたり、メールジョブと組み合わせてみたり、テストを書いてみたりしてみた

Rails + Active Job + Delayed::Jobな構成でジョブを作ってみた時に、色々調べたためメモを残します。 なお、記事が長いため、途中のソースコードは説明使う部分以外を省略しています。 必要に応じて、実際のソースコードを Github リポジトリでご確認くださ…

Rails7で導入された構文を使って、ActiveRecord::Enumを使ってみた

Railsのモデルで「(いわゆる)マスタを作るほどでもないけど数値に名前をつけたい」という時に、 ActiveRecord::Enum (enum) が使えます。 ActiveRecord::Enum enum については、以下をはじめ、詳しく解説している記事がすでに存在します。 Railsのenumを使い…

Rails製APIにて、JavaScriptの fetch() に対してリダイレクト的なステータスコードを返したい時はどうすればよいか調べてみた

Railsのコントローラにてリダイレクトをしたい時は redirect_to が使えます。 2.3 redirect_toを使う | レイアウトとレンダリング - Railsガイド 以下の例では、コントローラの show() へルーティングされた時に after_redirect_erb_fruits_path へとリダイ…

Rails + RSpecで、メモ化しているメソッドをモックしたら RSpec::Mocks::ExpiredTestDoubleError になったので、調べてみた

Rubyでメモ化したい時、 ||= を使って書くことがあります *1。 以下のコードであれば、クラスメソッド twitter を使って、クラスインスタンス変数 @twitter に Api::External::Twitter.new のインスタンスを設定・メモ化しています。 class Api::External::C…

React + Rails + Vite.js なSPAアプリを、RubyMineを使ってReactとRailsの両方をデバッグしてみた

JetBrainsの資料にある通り、RubyMineではRailsに加えてReactもデバッグできます。 Debug a React application - React | RubyMine Debugging React Apps Created With Create React App in WebStorm | The WebStorm Blog Reactのデバッグについては、公式…

Rails + Committeeで書いたテストコードが TypeError: no implicit conversion of String into Integer で落ちたため対応してみた

OpenAPIスキーマのあるRails製APIサーバにて、テストコードを Committee + Committer::Rails で書いていたところ、 TypeError: no implicit conversion of String into Integer というエラーが出ました。 エラーを解消するまでに少々悩んだため、メモを残し…

Ruby版のOpenAPI generatorで生成したAPIクライアントが、enumの定義にない値をレスポンスで受け取るとエラーになってしまうので、回避策を実施してみた

OpenAPIスキーマで enum を使うと、その項目が取り得る値を指定できます。 Enums - DataModels (Schemas) - OpenAPI Guide - swagger 例えば、以下のOpenAPIスキーマのようにレスポンスの型が定義されているAPIの場合、HTTPレスポンスボディの shop が取り得…

Railsで、wrap_parametersで追加されたキーに対し、Strong Parametersのrequireやpermitを使ってみた

Rails製のAPIに curl -X POST 'http://localhost:3000/wrap_parameter/outputs' -H "Content-Type: application/json" -d '{"name":"foo", "age": 20}' なリクエストを投げたところ、ログに Started POST "/wrap_parameter/outputs" for 127.0.0.1 at 2022-0…