SNSでシェアする

Railsの外部キー(user_idなど)を参照先テーブルと異なるカラム名に設定する方法

SNSでシェアする

スポンサーリンク
 
是非購読クリックお願いします☆

Ruby_on_Rails_logo

Railsで、とあるカラムに外部キーを設定する場合、
「参照先のテーブル名と同じカラム名+_id」などと外部キーを付けてあげなくてはいけませんよね。

例:ArticleモデルとUserモデルがある場合、articlesテーブルに「user_id」カラムを追加する、みたいなことです。この「user_id」のことを外部キーというんですねー。

上記の例のようなuser_idという外部キー名に違和感が無い場合はいいのですが、「この外部キーの名称ちょっと違和感あるな…わかりづらい…」な〜んて思うことが時々出てきます。

そこで、適切且つわかりやすい外部キーの名称をカラム名として付けてあげたいという要望が出てくるわけなんですね。(だってそっちの方がわかりやすいし)

しかし、ただ普通に「任意で付けたい名称+_id」と、こちらの好き勝手に外部キー(カラム)を作っても、いざ動かそうとしてもちゃんと参照してくれないんですね。

これは、外部キーは必ず「参照先テーブルと同じ名称+_id」でというルールがあるからです。

そこで、この問題を解決するための方法をメモとして書き留めておきます。(めっさ簡単です)

動作環境

Rails 4.2.5

まず、外部キーの名称に違和感あるってどんな時だよって話

そもそも、外部キーの名称に違和感を感じる状況ってどんな時なんだ?って話なのですが、、、

実際に私がその問題に直面した時の例を元に見ていきたいと思います。

こんな状況の時の外部キー名って違和感じゃね?

私が直面した状況としては、まず記事を管理しているArticleモデルというものと、エンドユーザーではなく運営管理者側のユーザーを管理するためのAdminUserモデルというものが存在しています。(エンドユーザーを管理するためのUserモデルももちろん別にあります)

そんな、Articleモデル、AdminUserモデルがある状況において、articlesテーブルには記事が大量に保管されているわけです。

その各記事に対して、記事を公開するためにadmin_usersテーブルのインスタンス(サイト管理者の誰か)は各記事の内容を自由に編集することができ、投稿する事ができます。

そこで、「どの記事を、誰が編集したのか」を識別するために、articlesテーブルに「admin_user_idカラム」(外部キー)を追加して解決しよう!となったわけなんですね。

そうした場合、アソシエーションは以下のように設定することになるでしょう。

よし、これで解決!!と思ったのですが、、、

よく考えてみると今回の場合、「各記事を編集したのは誰なのか」ということを識別するためのものなので、「admin_user_id」(管理者)という外部キーの名称はちょっと違和感があるように思えてくるわけです。

というより、非常にわかりづらい外部キーの名称であることが感じられるはずです。

そこで考えた結果、この場合は「editer_id」(編集者のid)みたいな外部キーの名称だとわかりやすくていいよね!ってことになり、articlesテーブルには「admin_user_id」という名称ではなく、「editer_id」という名称の外部キーを作ろう!となったわけなんです。

解決方法

外部キーを自分で付けた任意のものにした場合(今回の場合は「editer_id」)、外部キーを追加したモデルのアソシエーションの記述を以下のように記述すればちゃんと参照してくれるようになります。

class_nameを指定し、任意で付けた名称の外部キーが、どのモデルを参照しているのかというのを設定してあげるだけなんですね。

カラム名は「editor_id」という外部キーにしたわけですが、belongs_toで指定するのは_idは無しの「:editor」だけで指定します。(belongs_toの引数に「_id」があるとエラります)

たったこれだけの記述で、articlesテーブルに追加された任意の名称である外部キー(editer_idカラム)をちゃんと参照してくれるようになりました。

まとめ

いかがでしたでしょうか? めっさ簡単ですよね!

こんなに簡単に外部キーを任意の名称のものに設定できるのであれば、これからはちゃんと適切な名称で付けてあげることを心がけていきたいですね。

変数名はもちろん、外部キー名もちゃんとわかりやすく適切な名称を付けてあげましょう!

スポンサーリンク
スポンサーリンク