🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1493閲覧

RailsでのSTI実装(中間テーブルを使用した)での関連付け

tanamasa

総合スコア7

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2019/11/20 14:09

イメージ説明

概要

ユーザーと使用したいテーブル、を中間テーブルで多対多の関連を付けました。

使用したいテーブルにはSTI(単一テーブル継承)で、sample1とsample2のモデルを継承したいです。
使用したいテーブルにはTypeカラムを設置しています。

この場合、中間テーブルに設置する使用したいテーブルの外部キーは使用したいテーブル_idでいいのでしょうか?

users.使用したいテーブルでデータを取得しようとすると、sample1ないしsample2にアクセスしたいのに、使用したいテーブルに直接アクセスしてしまいます(理屈はわかります)。

関連付けの記述は下記の通りです。

usersモデル

has_many :中間テーブル has_many :使用したいテーブル, through: :中間テーブル

中間テーブルのモデル

belongs_to :user belongs_to :使用したいテーブル

聞きたいこと

どのような関連付けの記述をすれば、このER図通りに実装できますでしょうか?

アドバイスでもいいので、よろしければ教えて頂けると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

sample1 を参照したいなら Userでの関連付けを
has_many :sample1s, through: :中間テーブル とし
user.sample1 とする必要があります

sample2についても同じ定義が必要です。つまり、1用2用の二つの中間テーブルが必要です。
もっとも、1も2も使用したいもDBの実体は一つのtableでidの衝突はないでしょうから、一つの中間テーブルでも動くかもしれない。それは実験!

質問に書いてあるような関連付けでは 使用したい のモデル参照になります。

sample1,2で個別に関連を付けない理由、
「使用したいテーブル」とありながら参照したいのはそのモデルではなく1,2である理由
がわかるともう少し役に立つ回答が書けるかもしれません

投稿2019/11/20 21:47

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanamasa

2019/11/21 03:22

ご回答ありがとうございます! >sample1,2で個別に関連を付けない理由 これに関しまして、sample1と2はテーブルを作成していません。なのでhas_many :sample1とすると「テーブルがありません」などのエラーが出てしまいます。 STIの考えではsample1,2のテーブルは作成しないと思っていましたが、これが間違っているのでしょうか? >「使用したいテーブル」とありながら参照したいのはそのモデルではなく1,2である理由 がわかると このER図で通知機能を実装しようとしています。「全体通知」と「個別通知」で分けたいのですが、通知のテーブル構造は同じなのでシングルテーブルで実装し、STIの概念で区別しようと考えています。 追加で申し訳ありませんが、よろしければご教授お願い致します!
winterboum

2019/11/21 04:02

> has_many :sample1とすると「テーブルがありません」などのエラーが出てしまいます。 そういうことが起きますか!  STIだったら親のtableを継承しているかとおもってました。 こんなことをして良いのかわかりませんが class Sample1 に self.table_name = "使用したいテーブルのdb TABLE名" ってしたらどうなりますか?
winterboum

2019/11/21 04:06

「全体通知」と「個別通知」 この程度の差でしたら(methodが違うとか無いのなら)STIにしないで、class 使いたいテーブル に scope :sample1, -> {where(type: "sample1") } とするくらいでよいのでは? ただ、この場合は名前は type にしないほうがよいかも、。多分これ ActiveRecodeの予約語ですからどっかでおかしなことが起きないとも限らない
tanamasa

2019/11/21 06:22

>self.table_name = "使用したいテーブルのdb TABLE名" なるほど、返り値を明示してあげるんですね!やってみます! >この程度の差でしたら(methodが違うとか無いのなら)STIにしないで、class 使いたいテーブル に scope :sample1, -> {where(type: "sample1") } そうですね!試行錯誤して上手くいかなければそちらでやってみようと思います! めちゃめちゃわかりやすかったです。ありがとうございました!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問