Rails

route.rbのルーティングについて
resourceを使うと、アクションが自動で割り振られる
リソースベースのルーティング (以下リソースルーティング) を使うことで、リソースベースで構成されたコントローラに対応する共通のルーティングを手軽に宣言できます。resourcesを宣言するだけで、コントローラのindex、show、new、edit、create、update、destroyアクションを個別に宣言しなくても1行で宣言が完了します。

マイグレーションにadd_indexを付与すると、データ検索する時に高速になる。

CRUDについて

サーバー側にAPIリクエストを送信する際に以下のエラーが表示された。
ERROR [HPM] Error occurred while proxying request localhost:3000/xxx to http://localhost:3002/ [ECONNRESET] (https://nodejs.org/api/errors.html#errors_common_system_errors)
結果としては、DB(postgresql)の起動が出来ていないのが原因だった。
brew services list
でステータスを見て、postgresqlのステータスがerrorになっていた。
ちなみにこのコマンドでもレスポンスが返ってなかった。
pg_isready
/tmp:5432 - no response
MacのFinderでメニューから「移動」→「フォルダへ移動」を選択し、「postgresql.log」を探した。
ここにpostgresqlの実行ログが残っていた。
postgresqlを実行すると以下の様な表示になる為、起動に成功したと勘違いしてしまったが、postgresql.logでは失敗していたのでそちらを対応する必要があった。
$ brew services start postgresql@14
==> Successfully started `postgresql@14` (label: homebrew.mxcl.postgresql@14)
自分の場合はカーネルの容量が不足していたのが原因だったらしい。実際のログはこんな感じ。
LOG: database system is shut down
FATAL: could not create shared memory segment: Cannot allocate memory
DETAIL: Failed system call was shmget(key=11348575, size=56, 03600).
HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.
The PostgreSQL documentation contains more information about shared memory configuration.
カーネルの容量を増やしてみた。
(参考 : https://ytkyk.info/blog/2013/05/11/macでpacketsdtpserverを使うときのshared-memoryの設定/)
$ sudo sysctl -w kern.sysv.shmall=1073741824
kern.sysv.shmall: 1024 -> 1073741824
接続できる様になった。
$ pg_isready
/tmp:5432 - accepting connections
postgresqlの起動が上手くいくと、http://localhost:3002/ にアクセスしてRailsのページが表示される様になった。この状態で試したらエラーが解消された。

ridgepoleについて

paranoiaで論理削除を実現する

DBのログをローカルで確認
open /opt/homebrew/var/log/postgresql@14.log
これでカーネルの容量増やせる
sudo sysctl -w kern.sysv.shmall=1073741824

ridgepoleをローカル環境で実行時に以下のエラーが出た。
[ERROR] database configuration does not specify adapter
database.yml
にローカル用の設定がないのが原因だったので追加した状態で実行したらエラーが解消された。

psqlでよく使うコマンド
データベースへの接続を終了
\q
データベースの一覧表示
\l
データベースへの接続
\connect データベース名
作成済みのテーブルを一覧表示
\dt
個別のテーブルの確認
\d テーブル名

RspecではFacroryBotを使用してテストデータを作成できる。
テストユーザーを作成する場合はこんな感じで書ける。
create(:user)

RSpecの書き方に迷った時はこちらを見る。
以下の様に実行すれば特定のファイルの特定のテストだけを流せる
bundle exec rspec ./spec/hoge/fuga.rb:123

bundle exec rubocop -a
でコードを自動修正してくれる

bundle exec dotenv
コマンドがcommand not found: bundle exec dotenv
エラーになった。
bundle -v
やdotenv -v
は問題なかったので、コマンドはインストールされている。
-E
オプションが正しく設定されていないのが原因で、正しい値に設定し直したらエラーが解消された。
メモ帳からコピーしても失敗することがある。

Railsでenumを扱う

eager_load
について

非同期処理を実行するSidekiqについて

DBの正規化
候補キーの一部に従属するカラムは別テーブルに切り出す

railsのincluded do
について
このブロックの中にメソッドを定義しておくとモジュールがincludeされたあとににそのメソッドが動作する。

Scopeについて
メソッドチェーンを1つのメソッドとして定義して簡潔に記述できる。

デッドコードを検出するツールdebrideについて
オプションで特定のファイルやメソッドの除外も可能

Rakeタスクについての分かりやすい記事

バッチ処理についての比較記事

rakeタスクを作成する際に、:environment
を指定しないとRailsアプリの読み込みが出来ず、クラスやモジュールの参照ができない。

AWS Athenaのパーティションについて。Partition Projectionを使うと自動でパーティションを追加できる。

rakeタスクを早期リターンする場合は、returnではなくnextを使う。
returnすると、LocalJumpErrorになる。

時間をメソッドチェーンを使ってmockする。
allow(Time).to receive_message_chain(:zone, :today).and_return('2024-03-15')
allow(Time).to receive_message_chain(:zone, :now, :yesterday, :to_date).and_return('2024-03-14')

rspecでs3をmockしたい時はこんな感じで書ける。
APIのレスポンスなど、instance_doubleを使ってmockしづらい場合はmock用のカスタムクラスを作ると良い。
let(:list_object_response) do
instance_double(
Aws::S3::Types::ListObjectsOutput,
contents: [
instance_double(Aws::S3::Types::Object, key: 'hoge'),
instance_double(Aws::S3::Types::Object, key: 'hoge'),
instance_double(Aws::S3::Types::Object, key: 'hoge')
]
)
end

icu4c
のバージョンが変わったことにより、postgres
が動かなくなった。
icu4c
の最新バージョンが入っているとダメらしい。以下のバージョンで73.2のバージョンに戻して対応した。
brew tap-new ihara/icu4c // ローカルにリポジトリを作成
brew extract --version=73.2 icu4c ihara/icu4c // 古いバージョンを探す
brew tap homebrew/core --force // homebrew/coreがなかったので作成
brew install ihara/icu4c/icu4c@73.2 // 73.2のバージョンをインストール
brew unlink icu4c // 現在のリンクを剥がす
brew link ihara/icu4c/icu4c@73.2 --force // リンクの付け替え
brew info icu4c // 新しいバージョンであることを確認
その他よく使うコマンド
brew services list
pg_isready
sudo sysctl -w kern.sysv.shmall=1073741824
kern.sysv.shmall: 1024 -> 1073741824
open /opt/homebrew/var/log/postgresql@14.log
brew info icu4c@73.2
brew --prefix icu4c@73.2
brew reinstall ihara/icu4c/icu4c@73.2
open ~/.zshrc
source ~/.zshrc

rubyのEnumeratorについて
複雑なループ処理を書く時には、外部イテレータを使用する方法もある。

RSpecのSubjectについて

// Formulaに移動
cd /opt/homebrew/Library/Taps/homebrew/homebrew-core/Formula
// lsするとiというディレクトリがあるので移動
ls | grep icu4cでicu4c.rbがあればOK
git log --oneline icu4c.rbで該当のコミットを探す
git checkout 9ca237a7bc8 icu4c.rbで切り替え
この状態で以下を試してインストール
// 古いicu4cを入れる
brew uninstall icu4c@73.2 // Tapで作った余計なバージョンを一旦アンインストール
https://qiita.com/y_sone/items/f34cd19c6f02d34a9f89
brew list icu4c --versions // この時点では74.2
HOMEBREW_NO_AUTO_UPDATE=1 brew reinstall icu4c.rb // いれなおす
// HOMEBREW_NO_AUTO_UPDATE=1がないと最新バージョンが入ってしまう
brew list icu4c --versionsでicu4c 73.2が出ていればOK
パスも通す
export PATH="/opt/homebrew/opt/icu4c/bin:$PATH"
export PATH="/opt/homebrew/opt/icu4c/sbin:$PATH"
$ brew info icu4c
==> icu4c: stable 74.2 (bottled) [keg-only]
C/C++ and Java libraries for Unicode and globalization
https://icu.unicode.org/home
/opt/homebrew/Cellar/icu4c/73.2 (268 files, 80.1MB) *
Poured from bottle on 2024-04-02 at 17:21:51
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/i/icu4c.rb
License: ICU
==> Caveats
icu4c is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS provides libicucore.dylib (but nothing else).
==> Analytics
install: 223,024 (30 days), 523,980 (90 days), 1,979,882 (365 days)
install-on-request: 11,563 (30 days), 23,357 (90 days), 70,140 (365 days)
build-error: 42 (30 days)
brew services listが問題なければOK

allow_any_instance_of
を使わない様にテストを書き換える
// 修正前
allow_any_instance_of(User).to receive(:hogehoge!)
.and_raise(StandardError)
// 修正後
allow(user_a).to receive(:hogehoge).and_raise(StandardError)
allow(User).to receive(:find_by).and_return(user_a)

HTTPリクエスト