[Ruby on Rails] 単数系と複数形でハマった時の解決方法
はじめに
電話自動応答サービスIVRyでエンジニアをやっている小瀬です。
IVRyではRailsを中心にバックエンドのコードを書いています。
開発中に溜まった知見などをzennブログの方に書いていこうと思っていますので、よろしくお願いします。
書き方は合っているのにassociationが反映されない
Railsを書いているとhas_manyとbelongs_toを定義してテーブルの関連付けをよくやると思います。
今回もいつもと同じように定義したのに、なぜか反映されず、ハマりました。
エラーメッセージをよく見る
実際のモデル名とは違いますが、同様の事象を説明できるのでモデル名を MyBase として説明します。
テーブル名はmy_bases
でMyBase
というモデルクラスを定義しました。
エラーメッセージをよく見ると
Rails couldn't find a valid model for MyBasis association.
自分が定義したのはMyBase
なのにMyBasis
を見つけることができませんと書いてあります。
勘がいい人ならもう気づいたと思いますが、どうやら英語の単数系と複数形の問題にぶち当たっていたようです。
Railsに登録されている単数系と複数形を調べる
Railsに登録されている単数系と複数形を調べるには、singularize
とpluralize
というメソッドを文字列に対して実行するだけです。
早速調べてみました。
'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には壁もありますし
めちゃくちゃいいスピーカーもあります。そしてなにより事業もすごいスピードで伸びています!
切実に人が足りません!笑
IVRyで働くことに興味ある方、是非ご連絡ください!
Discussion