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

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

ただいまの
回答率

90.04%

cakePHP データベース リレーションシップの考え方

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 1,121

numa

score 30

現在cakePHPでデータベースを勉強中の者です.

こちらのサイトに掲載されている情報に沿ってデータベースの扱い方を勉強しているところです.
http://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html#id2

まだこのページのbelongsToの項目までしか知識が無いのですが,私の理解度が乏しく,hasOneとbelongsToを1対1,多対1,と考える事に納得できません.
これら2つは対になっていて読み取る側と読み取られる側のどちらを基準に考えるかで使い分けると理解しています.なので私は基準が変わると1対1になったり,多対1になるという部分が腑に落ちません.

例えば[ユーザテーブル]と[プロフィールテーブル]があり,プロフィールテーブルに"user_id"という項目があったとします.

場合1)ユーザモデルからプロフィールテーブルの情報を読み取る際
ユーザモデルにはhasOneを記述(1対1)

これはユーザを基準にしていて,1つのユーザにつき1つのプロフィールがあると考えれば納得できます.


場合2)プロフィールモデルからユーザテーブルの情報を読み取る際
プロフィールモデルにbelongsToを記述(多対1)

これは基準がプロフィールになっていて,実際は場合1と同じく1つのプロフィールにつき1つのユーザのはず,なのでこの場合もユーザとプロフィールの関係は1対1だと思うのですが….


cakePHPだけがこの考え方なのでしょうか?
これらの分かりやすい例え方等があれば教えてください.

よろしくお願いいたします.
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

userTable(親)
id(PK)
user_name
.
.
.

ProfilesTable(子)
id(PK)
user_id(FK)
.
.
.
の時、
親モデルが子モデルを引っ張る場合はhasOne(あるいはhasMany)
子モデルが親モデルを引っ張る場合はbelongsTo
です。

class User extends AppModel {
    public $hasOne = array(
        'Profile' => array(
            'className' => 'Profile',
            'conditions' => array('Profile.published' => '1'),
            'foreignKey' => 'user_id',
            'dependent' => true
        )
    );
}

class Profile extends AppModel {
    public $belongsTo = array(
        'User' => array(
            'className' => 'User',
            'foreignKey' => 'user_id'
        )
    );
}

UserテーブルとProfileを繋ぐキーはProfileのuser_idであることを伝えないといけないのです。
Userモデルから見たら、hasOne(指定したクラスの方に参照するキーがあるよ)
Profileモデルから見たら、belongsTo(こっちに参照するキーがあるよ)
ってくらいの違いですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/19 14:59

    回答ありがとうございます.

    場合2についてですが,
    これまでは1つのプロフィールが必ず1つのユーザに**属す**と考えていましたが,
    それではbelongsToの”属す”という捉え方では無く,hasOneの”持つ”という考えに近いことに気が付きました.

    ここでは,複数あるプロフィール情報は,各々がどれか1つのユーザに属している,と考えるとbelongsTo(属す)(多対1)で2つの情報を結び付けられる事にも納得です.

    また,場合1については,複数あるユーザ情報は,各々がどれか1つのプロフィールに**属す**,ではなく,1つのユーザは1つのプロフィールを**持つ**,と考えhasOneを用いる.と捉えれば両方に納得できました.


    初めての概念だったので複雑に考えてしまいましたが,プログラム的にはそこまで考える事では無さそうですね.

    キャンセル

  • 2015/11/19 15:08

    あっ、補足なのですが
    > 1つのユーザは1つのプロフィールを**持つ**
    1つのユーザは1つのプロフィールを持っているか、あるいは持っていない。
    というケースがあることを忘れないようにしてください。

    cakePHPはこれらのリレーションの考えをプログラマ寄りのわかりやすく使えるようにしたものですが、DB設計者からすると「厄介な…」と思ってしまうFWでもあります。
    ただ、まだcakePHPを学び始めたばかりというのであれば、複雑に考える必要はありません。使える機能はジャンジャン使いましょう!

    キャンセル

  • 2015/11/19 15:37

    まだまだcakePHPは初心者なので,これからどんどん機能を使っていく内にプログラム的な見方が出来るようになり,腑に落ちる考えに辿りつけるかも知れませんね!
    ありがとうございました!

    キャンセル

0

この問題はテーブル同士を繋ぐためのキーに着目する必要があるようですね.

プロフィールテーブルにはuser_idというカラムがあり,1つのレコードに設定できるuser_idの値は1つですが,テーブル全体を見ればuser_idが同じ値のレコードは複数ある場合とそうでない場合があります.

それに比べてユーザテーブルのid列には(主キーなので当たり前ですが)同じ値はありません.

よってプロフィールテーブルのuser_idから辿ると1対1,もしくは多対1となります.
これはどちらの場合もユーザに属していると言えるのでbelongsTo(属す)を扱うことに問題はありません.

ユーザテーブルのuser_idから見れば1対1,もしくは1対多になります.
これはプロフィールを1つ持つ場合はhasOne,複数持つ場合はhasMany.と使い分ける必要があるようです.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる