🎉

[Ruby on Rails] 単数系と複数形でハマった時の解決方法

2022/10/20に公開約2,300字

はじめに

電話自動応答サービスIVRyでエンジニアをやっている小瀬です。
https://twitter.com/ats312kose

IVRyではRailsを中心にバックエンドのコードを書いています。
https://ivry.jp/

開発中に溜まった知見などをzennブログの方に書いていこうと思っていますので、よろしくお願いします。

書き方は合っているのにassociationが反映されない

Railsを書いているとhas_manyとbelongs_toを定義してテーブルの関連付けをよくやると思います。
今回もいつもと同じように定義したのに、なぜか反映されず、ハマりました。

エラーメッセージをよく見る

実際のモデル名とは違いますが、同様の事象を説明できるのでモデル名を MyBase として説明します。
テーブル名はmy_basesMyBaseというモデルクラスを定義しました。
エラーメッセージをよく見ると

Rails couldn't find a valid model for MyBasis association.

自分が定義したのはMyBaseなのにMyBasis を見つけることができませんと書いてあります。
勘がいい人ならもう気づいたと思いますが、どうやら英語の単数系と複数形の問題にぶち当たっていたようです。

Railsに登録されている単数系と複数形を調べる

Railsに登録されている単数系と複数形を調べるには、singularizepluralizeというメソッドを文字列に対して実行するだけです。
早速調べてみました。

'my_base'.pluralize
=> "my_bases"
'my_bases'.singularize
=> "my_basis"

baseの複数形はbasesなのに対して、basesの単数系はbasisと登録されていたのです。
これにより、Railsは、my_basesという名前からMyBasisというクラスを探しにいっていたのです。
だから、Railsはそんなクラス無いよーとなり、関連付けをすることができてなかったんですね。

※ この問題は関連付けだけでなく、色んな場面でエラーが起きると思います。僕が最初に気づいたのが関連付けのコードだったので例として書いています。

解決策

今回自分が使いたい意味としては、basisの方ではなかったため、Railsに登録されている単数系と複数形を修正することで対応しました。
修正方法は
config/initializers/inflections.rb

ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.irregular 'my_base', 'my_bases'
end

と書くだけです。
baseという単語は広く使われていそうなので、念の為、my_baseとアンダーバーで繋いだ実際のテーブル名を書きました。
問題なく動作するので、影響範囲を小さくするために実際のテーブル名を書くことをオススメします。

念の為rails consoleで確認すると複数形と単数系の変換が狙い通りになっていることが確認できました。

'my_base'.pluralize
=> "my_bases"
'my_bases'.singularize
=> "my_base"

[番外編]よく言われるややこしい複数形を調べてみた

irb(main):011:0> 'samurai'.pluralize
=> "samurais" # 英語ではsamuraiのまま
irb(main):005:0> 'fish'.pluralize
=> "fish" # 英語と同じで複数形なにも変化しないのか...
irb(main):006:0> 'child'.pluralize
=> "children" # 英語と同じ
irb(main):007:0> 'tooth'.pluralize
=> "tooths" # ここはteethではなくtooths
irb(main):008:0> 'foot'.pluralize
=> "foots" # ここもfeetではなくfoots
irb(main):009:0> 'mouse'.pluralize
=> "mice" # ここはmiceなんかい

英語通りだったり単にsがついたり、sがつかなかったり、変形したりしなかったり、かなりややこしいことがわかりました。笑
英語は本当にややこしいですね。
今回僕が踏んだのはRailsじゃなく英語の単数系と複数形のバグなんだな思ってきました。笑

最後に会社の宣伝

IVRyには壁もありますし
https://note.com/u16m/n/n3b31ede1065e
めちゃくちゃいいスピーカーもあります。
https://note.com/kose_atsuya/n/n6889336dd3d7

そしてなにより事業もすごいスピードで伸びています!
切実に人が足りません!笑
IVRyで働くことに興味ある方、是非ご連絡ください!

https://ivry-jp.notion.site/IVRy-e1d47e4a79ba4f9d8a891fc938e02271

Discussion

ログインするとコメントできます