質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails

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

Q&A

解決済

1回答

3076閲覧

アソシエーションの考え方/has_many & belongs_to

PartyKids

総合スコア65

Ruby on Rails

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

0グッド

0クリップ

投稿2017/05/03 08:45

編集2017/05/03 19:52

GW中ありがとうございます。
rails tutorialや本を何度読み返したり、図にしたりしても日本語が分からず、理解できないので助けてください。

###疑問
外部キーの意味が良くわからないため、詰まっています。
has_many や belongs_to は、テーブル間の関係性を表すもので、実際にテーブル間を繋げるのは外部キーによってである。っという考え方をしていました。が、その考え方だと、詰まってしまうので、助けてください。

ruby

1 2###user.rb 3has_many :microposts, dependent: :destroy 4has_many :active_relationships, class_name: "Relationship", 5 foreign_key: "follower_id", 6 dependent: :destroy 7 8###microposts.rb 9belongs_to :user 10 11###relationships.rb 12belongs_to :follower, class_name: "User" 13belongs_to :followed, class_name: "User"

ruby

1###schema.rb 2create_table "users", force: :cascade do |t| 3 t.string "name" 4 t.string "email" 5 t.datetime "created_at", null: false 6 t.datetime "updated_at", null: false 7 t.string "password_digest" 8 t.string "remember_digest" 9 t.boolean "admin", default: false 10 t.string "activation_digest" 11 t.boolean "activated", default: false 12 t.datetime "activated_at" 13 t.string "reset_digest" 14 t.datetime "reset_sent_at" 15 t.index ["email"], name: "index_users_on_email", unique: true, using: :btree 16 end 17 18create_table "microposts", force: :cascade do |t| 19 t.text "content" 20 t.integer "user_id" 21 t.datetime "created_at", null: false 22 t.datetime "updated_at", null: false 23 t.string "picture" 24 t.index ["user_id", "created_at"], name: "index_microposts_on_user_id_and_created_at", using: :btree 25 t.index ["user_id"], name: "index_microposts_on_user_id", using: :btree 26 end 27 28create_table "relationships", force: :cascade do |t| 29 t.integer "follower_id" 30 t.integer "followed_id" 31 t.datetime "created_at", null: false 32 t.datetime "updated_at", null: false 33 t.index ["followed_id"], name: "index_relationships_on_followed_id", using: :btree 34 t.index ["follower_id", "followed_id"], name: "index_relationships_on_follower_id_and_followed_id", unique: true, using: :btree 35 t.index ["follower_id"], name: "index_relationships_on_follower_id", using: :btree 36 end

###私の考え
user と micropostの関係性
userは複数の呟き(micropost)をする事が出来るので、user.rbにhas_manyと書く。逆に一つの呟きは必ず一人のユーザーによってなされるため、belongs_toを書く。

user と micropostの外部キー

Railsはデフォルトでは外部キーの名前を<class>_idといったパターンとして理解

ここから、よく意味が分からなくなりました。。。

user.rb に has_many :micropostsっと書けるのは、micropostsテーブルにuser_idカラムがあるから?

逆に、microposts.rb に belongs_to :user と書いているが、usersテーブルにmicroposts_idカラムなんてないけど。。。。

質問するにあたって、まとめて整理してみましたが、やっぱり意味が分からず、支離滅裂な質問文になってしまいましたが、よろしくお願いいたします。

###追記
モデルAとモデルBがあり、テーブルAの情報をテーブルBに組み込みたいと仮定する(1対多)。
この時の主キーは、テーブルAのID(一意)であり、モデルBにあるa_idが外部キーとなる。

ruby

1###a.rb 2has_many :b 3 4 5###b.rb 6belongs_to :a

a,bは、モデル自身が見るべきモデルクラスを示唆しているだけで、外部キーや主キーの情報ではない。
a.rbは、has_many: b の b から、model class B を見て、自身のモデルクラス_IDがあることを知り、a→bのモデルが結合する。

逆に、b.rbは、belongs_to :a の a から、model class a を見て、自身のモデルクラス_IDがないため、aの主キーをベースに、b→aのモデルが結合する。

って事ですか?

ruby

1 2has_many :active_relationships, class_name: "Relationship", 3 foreign_key: "follower_id", 4 dependent: :destroy

上記のコードで、『foreign_key: "follower_id"』っと記載しているのは、これを書かなかったら、active_relationshipsテーブルの主キーを外部IDと認識してしまうため、書いているのですか?

長文で申し訳ないですが、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

has_many や belongs_to は、テーブル間の関係性を表すもので、実際にテーブル間を繋げるのは外部キーによってである。

「モデル間の関係性を定義するもの」と考えたほうが適切な気がします。

user.rb に has_many :micropostsっと書けるのは、micropostsテーブルにuser_idカラムがあるから?

逆に、microposts.rb に belongs_to :user と書いているが、usersテーブルにmicroposts_idカラムなんてないけど。。。。

has_many、belongs_to は関連モデルにアクセスするメソッドを定義するための記述と考えればよいです。

  • user.rb に has_many ⇒ user.micropostsのメソッドを使用できるようにする
  • microposts.rb に belongs_to ⇒ micropost.userのメソッドを使用できるようにする

どちらもテーブルからデータを取得する際にはどちらも micropostsテーブルのuser_idカラムを使用します。

【補足】

外部キーについてはとりあえず以下の解釈でよいと思います。

  • テーブルは「主キー」を持つ
  • 関連する他のテーブルの主キーを指す列を「外部キー」と呼ぶ

ソースコードとデータベースの関係については以下のようになっています。

  • db:migrationでマイグレーションファイルからDBテーブル、インデックスを生成する
  • プログラム実行時にDBテーブルの列定義からモデルのフィールド定義を生成する

上の通りの関係なので、モデルに記述したhas_many や belongs_toはDBテーブルには影響を与えません。
※初めてrailsプログラム作成した頃は、db:migrationでテーブル作成する際にモデルに記述したhas_many や belongs_toがテーブルの関連に影響するものと勘違いしていました。

投稿2017/05/03 09:41

編集2017/05/03 11:33
tkmtmkt

総合スコア1800

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

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

PartyKids

2017/05/03 10:10

先日は、大変お世話になりました!そして、今回もありがとうございます! >どちらもテーブルからデータを取得する際にはどちらも micropostsテーブルのuser_idカラムを使用します。 両方から使用できるために、双方のモデルにアクセスするメソッドを書くんですね? 外部idがいまいち分からないのですが。。。。
PartyKids

2017/05/03 10:48

外部キーとは、対応するテーブルのカラムの事ではないのですか? よろしくお願いいたします。
tkmtmkt

2017/05/03 11:34

その解釈で間違いではないです。
PartyKids

2017/05/03 11:51

返信ありがとうございます! >microposts.rb に belongs_to :user と書いているが、usersテーブルにmicroposts_idカラムなんてないけど。。。。 個々の部分で、上記の解釈をすると詰まってしまうんです。 user = User.find(1) user.id でしたら、ユーザーIDを取得する事が可能なのですが。。。。
PartyKids

2017/05/03 11:52

すみません、補足を追加して頂けたんですね! 読み飛ばしていたので、読みます!
PartyKids

2017/05/03 19:47

主キーと外部キーを意識して、本を読み込んでみましたが、いまいち理解が出来なかったので、追記いたしました。 よろしくお願いいたします!
tkmtmkt

2017/05/04 14:15

「外部キー」という単語に脳内ストーリーを盛りまくって悩んでいるように感じられます。具体的な問題が何か整理して一つづつ片づけていってはどうでしょう。
PartyKids

2017/05/05 06:42

>「外部キー」という単語に脳内ストーリーを盛りまくって悩んでいるように感じられます。 仰る通りです(恥ずかしい。。。) GW中にrails tutrorialを終わらせたくって焦っていました。 少し回り道をして、考えたいと思います。 GW中に回答して頂き、誠にありがとうございました! 良い週末をお過ごしください 今回も助けて頂き、誠にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問