Hisakeyのブログ

エンジニアが色々呟くブログです。

技術記事

Ruby/Railsのメモ化について、詳しく調べてみた。

はじめに この記事では、Ruby/Railsのメモ化 をハンズオンで確認します。 「メモ化をすると内部で何が起きるのか?」という疑問に対して、低レイヤ(参照・割り当て・GC)の視点で手を動かして確かめます。 背景・動機 Rails で I/O(DB/HTTP)を伴う処理に…

Rails:非カラム属性(attribute)にenumを使う方法 ― 仕組みと実例

はじめに Rails 7.1.2 で 非カラム属性(non-column-backed attribute)に対して enum を再び使えるようになりました。ところが、この変更はブログ等であまり解説されておらず、理解に時間がかかったため、自分用の整理も兼ねて記事化します。 単なる使い方…

さくらVPSにVite + ReactをNginxでデプロイしてみた

はじめに 今回の記事は、さくらVPSのようなIaaSを使って「サーバー構築からデプロイまで一から理解したい」 という思いから書いています。 普段はPaaSやホスティングを使えば簡単にWebアプリを公開できますが、あえてIaaSを選んで「サーバーの中で何が起きて…

後編:【Rails失敗談】has_oneをオーバーライドした結果、バリデーションを追加したら、全テストが失敗した

はじめに Railsのhas_oneやhas_manyといったアソシエーションは、モデル同士の関連を簡単に扱える強力な仕組みです。しかし、このアソシエーションメソッドを安易にオーバーライドすると、思わぬ副作用が発生し、予期しないオブジェクト生成やテスト失敗の原…

前編:【Rails失敗談】アソシエーションを不用意にオーバーライドしてはいけない理由と安全な代替案

はじめに Railsのhas_oneやhas_manyといったアソシエーションは、モデル同士の関連を簡単に扱える強力な仕組みです。 しかし、このアソシエーションメソッドを安易にオーバーライドすると、思わぬ副作用が発生し、予期しないオブジェクト生成やテスト失敗の…

React(JavaScript)で複数ファイルを安全に一括ダウンロードする実装

はじめに 複数ファイルをまとめてダウンロードしたい場面は、ファイル管理系のアプリやエクスポート処理でよくあります。 ただし React でこれを実現しようとすると、await や setTimeout に頼った実装では、ファイルサイズやネットワーク速度によって動作が…

「はじめてのAST」〜parserとRubocopで構文木を学ぶ〜

はじめに ASTとはなにかというものを、簡単なコードを書きながら理解していく記事です。 今回は、parser を用いて Ruby のコードから AST(Abstract Syntax Tree)の構造を確認し、さらに Rubocop で簡単なカスタムCopを作成して、理解を深めてみました。 背…

TypeScriptのユニオン型で「登録か更新か」を型安全に判別する

はじめに TypeScript の discriminated union(判別可能なユニオン型)を導入することで、条件分岐をより安全かつ明示的に記述できるようになったことに気づいたので、それを共有します。 背景・動機 実務で、ユーザー情報の「登録」と「更新」を同じフォー…

ネストされたトランザクションを避けるためにブロックを使ったが、可読性が悪くなった

はじめに Railsでビジネスロジックをサービスクラスに切り出すことはよくあると思います。 中でも「データを更新して状態を進める」ような処理では、ApplicationRecord.transaction を使って整合性を保つことが多いと思います。 今回は、あるサービスが内部…

wrap_parameters というRails機能を知らずに、フロントエンドと異なるインターフェイスでも動いてしまった話

はじめに Rails API を使っていると便利な仕組みも多い一方、気づきにくい落とし穴もあります。 今回はwrap_parametersのいうRailsが用意している機能についてです 背景・動機 フロントエンドから以下のような JSON が送られてきたのですが: { "name": "Ali…

ActiveRecordの例外を明確に分けるために validate!を使ってみる

今まで、何気なく使っていた save! メソッドですが、どんな例外を返しているのかあまり意識していませんでいた。 今回は、どのような例外を返しているのか調べ、追加でvalidate!についても調べて見ました。 save! メソッドの例外 以下のような例外が発生しま…

saveメソッドとupdateメソッドの何が違うの?

Railsの開発でよく使う save と update。 どちらも「レコードを保存する」ためのメソッドですが、どのように実装されていて、どんな違いがあるのか?を意識してませんでした。 ActiveRecordのソースコードを参考に save と update の内部処理を比較し、何が…

reloadメソッドに沼りました。

はじめに Rails のコントローラーで User に紐づく全てのアソシエーションを preload して、N+1 を解消しようとしました。 user = User.preload(:posts, :comments).find(params[:id]) SQL のログを確認すると、 preload によって関連データがまとめて取得さ…

Railsにおけるパラメータ不足を考慮する

はじめに Railsのコントローラでは、リクエストパラメータを params から取得します。しかし、パラメータが必ず送られてくるとは限らず、不足している場合に適切な処理をしなければエラーや予期しない動作になります。 特に、外部に公開しているAPIでは、ク…

RSpecのlet, let!, before の違いと使いどころ

はじめに RSpec でテストを書く際に、データの準備方法として let, let!, before があります。 これらの使い分けを明確に理解していないと、意図しない動作をしてしまうことがあります。それぞれの使い方を記事にしてみました! 1. let と let! の違い RSpec…

Railsの遅延実行を理解して、無駄なクエリを防ぐ

はじめに RailsのActiveRecordは、データベースとのやり取りを簡単にする強力なツールですが、遅延実行という仕組みを正しく理解していないと、無駄なクエリが発生します。 遅延実行と即時実行の違いを明確にすることで、無駄なクエリを発生させないようにす…

Axiosの挙動: undefinedのパラメータについて

1. Axiosの特徴的な挙動 JavaScript の HTTP クライアントライブラリである axios には、リクエスト時に undefined の値を持つキーが削除されるという特徴があります。この仕様を利用すると、フロントエンド側で特定の条件に応じてパラメータを送信しないよ…

スネークケース・キャメルケースの変換と方法について

はじめに SS(サーバーサイド)とFE(フロントエンド)の開発で、特に意識せず進めてきましたが、ふと疑問に思ったことを記事にまとめてみました。 FEはキャメルケース、SSはスネークケースになっている理由 キャメルケースが使われる理由 (FE) JavaScriptや…

mark_for_destructionとは?

Railsの mark_for_destruction とは?基本的な使い方を解説! 初めて使用する機会があり、便利だなと思ったので記事にしました。 Railsでは、関連付けられたレコードを同時に更新することができます。中でも mark_for_destruction は、関連オブジェクトを削…

Transactionの挙動について

ネストされたTransactionにおける例外処理の挙動 今回、transactionの挙動について改めて勉強できたので、記事にしたいと思います Railsではtransactionメソッドを利用して、データベース操作を1つのトランザクションとして扱います。しかし、トランザクショ…

初回環境構築のスクリプトを更新しました!

概要 ※かなり雑な状態でのブログ記事となりますのでご了承ください macの初回環境構築って、大変ではないでしょうか? 初期設定完了後にやることは、 必要なアプリのインストール(chrome, firefox, etc) パッケージのインストール(ruby, node, etc) その他の…

Railsのenumで文字列を定義するメリットとデメリット

概要 実務で考える機会があったので、記事にしてみました。 Rails の enum 機能は、モデル内で状態を簡単に管理するための機能です。 通常、enumはintegerでDBに保存されるのですが、stringにすることで、DB上でぱっと分かりやすいので採用しました。 しかし…

RailsでのN+1問題を解消する方法:preloadとeager_loadの使い分け

概要 開発では、関連データを多く扱うためにN+1問題が頻繁に発生します。 今回、初めてN+1の解消を行う中で、曖昧だったpreloadとeager_loadについて、詳しく学ぶことができたので、記事にしてみました 内容 1. N+1とは 未経験のときには、曖昧な知識でした…

Railsの belongs_toと optional: true の動作について

概要 Rails の belongs_to アソシエーションにおいて、optional: trueを設定するかで、関連するオブジェクトのクエリ発行に違いがあることを知ることができたので、記事にしてみました。 内容 通常、belongs_to を設定すると、その関連付けはデフォルトで必…

Sidekiqに渡せる引数について理解する

概要 Sidekiqは、Ruby on Railsアプリケーションでよく使われる非同期のバックグラウンドジョブ処理ライブラリです。バックグラウンドジョブを使うことで、ユーザーが直接待つ必要のない処理を非同期で実行することができます しかし、Sidekiqではジョブに渡…

AASMから学ぶ、Railsのtransaction処理について

はじめに トランザクション処理とは トランザクションの基本について トランザクションとは、一連のデータベース操作をまとめて実行し、すべてが成功した場合にのみ変更を確定させる(コミット)機能です。もし途中でエラーが発生した場合は、すべての変更を…

ActiveRecord::RelationとActiveRecord::Associations::CollectionProxyってなに?

概要 実際の業務でrspecを書いてるときに発生し、理解に少し時間がかかったので記事にしました。 テストは同じ結果をみているはずなのにと思っていましたが、ActiveRecordのオブジェクトの違いで落ちていました。 内容 実務とは異なりますが、下記のようなア…

Rspecで、privateメソッドをテストする方法

概要 privateメソッドは、クラス内部の実装であるため、通常通りのテストができません。 publicメソッドのようにテストを書くとエラーになってしまいます。 今回、 Rspecでprivateメソッドをテストをする方法を学んだのでこちらに記事にしました 内容 privat…

mapメソッドとpluckメソッドの違い

概要 今回も、意識することなく使っていたメソッドです。 mapとpluckの違いについてまとめてみました! 内容 何が違うのか? map mapはRubyのArrayクラスのメソッドですが、Enumerableモジュールを介して他でも利用可能。 配列、ハッシュなどを繰り返し処理…

RSpecのbe_truthyとeq(true)の違い

概要 何気なく、使っていた下記のようなテストですが、 expect(subject).to be_truthy 正しく使い方を知らないと、通るテストを書いているだけ出会ったことを学んだので、共有します 内容 今回、テストを書こうとしていたものは下記のようなメソッドです def…