數(shù)據(jù)表之間是縱橫交叉、相互關(guān)聯(lián)的,laravel的一對(duì)一,一對(duì)多比較好理解,官網(wǎng)介紹滴很詳細(xì)了,在此我就不贅述啦,重點(diǎn)我記下多對(duì)多的關(guān)系

一種常見(jiàn)的關(guān)聯(lián)關(guān)系是多對(duì)多,即表A的某條記錄通過(guò)中間表C與表B的多條記錄關(guān)聯(lián),反之亦然。比如一個(gè)用戶(hù)有多種角色,反之一個(gè)角色對(duì)應(yīng)多個(gè)用戶(hù)。

為了測(cè)試該關(guān)聯(lián)關(guān)系,我們沿用官網(wǎng)的用戶(hù)角色示例:

需要三張數(shù)據(jù)表:users、roles 和 role_user,role_user 表按照關(guān)聯(lián)模型名的字母順序命名(這里role_user是中間表),并且包含 user_id 和 role_id兩個(gè)列。

多對(duì)多關(guān)聯(lián)通過(guò)編寫(xiě)返回 belongsToMany 方法返回結(jié)果的方法來(lái)定義。廢話(huà)不說(shuō)多,直接上數(shù)據(jù)結(jié)構(gòu):

1:創(chuàng)建一個(gè)角色表roles,并添加一些初始化數(shù)據(jù):

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'admin', 'admin@163.com', '$2y$10$J/yXqscucanrHAGZp9G6..Tu1Md.SOljX3M8WrHsUdrgat4zeSuhC', 'ilocXtjZJwhrmIdLG1cKOYegeCwQCkuyx1pYAOLuzY2PpScQFT5Ss7lBCi7i', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `users` VALUES ('2', 'baidu', '10940370@qq.com', '$2y$10$2A5zJ4pnJ5uCp1DN3NX.5uj/Ap7P6O4nP2BaA55aFra8/rti1K6I2', null, '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `users` VALUES ('3', 'fantasy', '1009@qq.com', '', null, '2017-06-14 10:38:57', '2017-06-15 10:39:01');

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

2:創(chuàng)建一個(gè)角色表roles,并添加一些初始化數(shù)據(jù):

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for roles
-- ----------------------------
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- ----------------------------
-- Records of roles
-- ----------------------------
INSERT INTO `roles` VALUES ('1', '超級(jí)版主', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `roles` VALUES ('2', '司令', '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `roles` VALUES ('3', '軍長(zhǎng)', '2017-06-14 10:38:57', '2017-06-15 10:39:01');
INSERT INTO `roles` VALUES ('4', '司長(zhǎng)', '2017-06-07 10:41:41', '2017-06-15 10:41:51');
INSERT INTO `roles` VALUES ('5', '團(tuán)戰(zhàn)', '2017-06-22 10:41:44', '2017-06-28 10:41:54');
INSERT INTO `roles` VALUES ('6', '小兵', '2017-06-22 10:41:47', '2017-06-22 10:41:56');

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

3:創(chuàng)建一個(gè)中間表role_user用于記錄users表與roles表的對(duì)應(yīng)關(guān)系,并添加一些初始化數(shù)據(jù):

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for role_user-- ----------------------------DROP TABLE IF EXISTS `role_user`;CREATE TABLE `role_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;-- ------------------------------ Records of role_user-- ----------------------------INSERT INTO `role_user` VALUES ('1', '1', '2', '2017-06-07 11:42:13', '2017-06-21 11:32:16');INSERT INTO `role_user` VALUES ('2', '1', '3', '2017-06-07 11:32:13', '2017-06-07 11:22:13');INSERT INTO `role_user` VALUES ('3', '2', '4', '2017-06-07 11:32:13', '2017-06-07 11:12:13');INSERT INTO `role_user` VALUES ('4', '1', '5', '2017-06-07 11:32:13', '2017-06-07 11:22:13');INSERT INTO `role_user` VALUES ('5', '3', '6', '2017-06-07 11:32:13', '2017-06-07 11:52:13');INSERT INTO `role_user` VALUES ('6', '3', '2', '2017-06-07 11:32:13', '2017-06-07 11:42:13');INSERT INTO `role_user` VALUES ('7', '2', '2', '2017-06-07 11:42:13', '2017-06-07 11:52:13');

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

注意我們定義中間表的時(shí)候沒(méi)有在結(jié)尾加s并且命名規(guī)則是按照字母表順序,將role放在前面,user放在后面,并且用_分隔,這一切都是為了適應(yīng)Eloquent模型關(guān)聯(lián)的默認(rèn)設(shè)置:在定義多對(duì)多關(guān)聯(lián)的時(shí)候如果沒(méi)有指定中間表,Eloquent默認(rèn)的中間表使用這種規(guī)則拼接出來(lái)。

創(chuàng)建一個(gè)Role模型:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

<?php

namespace App\Models;use Illuminate\Database\Eloquent\Model;/**
 * Class Role
 * @package App\Models
 * @mixin \Eloquent */class Role extends Model
{


}

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

然后我們?cè)?nbsp;User 模型上定義 roles 方法:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

<?php

namespace App\Models;use Illuminate\Database\Eloquent\Model;/**
 * Class User
 * @package App\Models
 * @mixin \Eloquent */class User extends Model
{    /**
     * 用戶(hù)角色     */
    public function roles()
    {        return $this->belongsToMany('App\Models\Role');
    }
}

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

注:正如我們上面提到的,如果中間表不是role_user,那么需要將中間表作為第二個(gè)參數(shù)傳入belongsToMany方法,如果中間表中的字段不是user_idrole_id,這里我們姑且將其命名為$user_id$role_id,那么需要將$user_id作為第三個(gè)參數(shù)傳入該方法,$role_id作為第四個(gè)參數(shù)傳入該方法,如果關(guān)聯(lián)方法名不是roles還可以將對(duì)應(yīng)的關(guān)聯(lián)方法名作為第五個(gè)參數(shù)傳入該方法。

接下來(lái)我們?cè)诳刂破髦芯帉?xiě)測(cè)試代碼:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

<? = User::find(1 = -> '用戶(hù)'.->name.'所擁有的角色:'(   ->name.'  '; //對(duì)應(yīng)輸出為:用戶(hù)admin所擁有的角色:司令  軍長(zhǎng)  團(tuán)戰(zhàn)

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 當(dāng)然,和所有其它關(guān)聯(lián)關(guān)系類(lèi)型一樣,你可以調(diào)用roles 方法來(lái)添加條件約束到關(guān)聯(lián)查詢(xún)上:

User::find(1)->roles()->orderBy('name')->get();

正如前面所提到的,為了確定關(guān)聯(lián)關(guān)系連接表的表名,Eloquent 以字母順序連接兩個(gè)關(guān)聯(lián)模型的名字。不過(guò),你可以重寫(xiě)這種約定 —— 通過(guò)傳遞第二個(gè)參數(shù)到 belongsToMany 方法:

return $this->belongsToMany('App\Models\Role', 'user_roles');

除了自定義連接表的表名,你還可以通過(guò)傳遞額外參數(shù)到 belongsToMany 方法來(lái)自定義該表中字段的列名。第三個(gè)參數(shù)是你定義關(guān)聯(lián)關(guān)系模型的外鍵名稱(chēng),第四個(gè)參數(shù)你要連接到的模型的外鍵名稱(chēng):

return $this->belongsToMany('App\Models\Role', 'user_roles', 'user_id', 'role_id');

定義相對(duì)的關(guān)聯(lián)關(guān)系

要定義與多對(duì)多關(guān)聯(lián)相對(duì)的關(guān)聯(lián)關(guān)系,只需在關(guān)聯(lián)模型中調(diào)用一下 belongsToMany 方法即可。我們?cè)?nbsp;Role 模型中定義 users 方法:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

<?php

namespace App\Models;use Illuminate\Database\Eloquent\Model;/**
 * Class Role
 * @package App\Models
 * @mixin \Eloquent */class Role extends Model
{    /**
     * 角色用戶(hù)     */
    public function users()
    {        return $this->belongsToMany('App\Models\User');
    }

}

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 正如你所看到的,定義的關(guān)聯(lián)關(guān)系和與其對(duì)應(yīng)的User 中定義的一模一樣,只是前者引用 App\Models\Role,后者引用App\Models\User,由于我們?cè)俅问褂昧?nbsp;belongsToMany 方法,所有的常用表和鍵自定義選項(xiàng)在定義與多對(duì)多相對(duì)的關(guān)聯(lián)關(guān)系時(shí)都是可用的。

測(cè)試代碼如下:

 = Role::find(2 = -> '角色#'.->name.'下面的用戶(hù):' (   ->name.' '

正如你看到的,處理多對(duì)多關(guān)聯(lián)要求一個(gè)中間表。Eloquent 提供了一些有用的方法來(lái)與這個(gè)中間表進(jìn)行交互,例如,我們假設(shè) User 對(duì)象有很多與之關(guān)聯(lián)的 Role 對(duì)象,訪(fǎng)問(wèn)這些關(guān)聯(lián)關(guān)系之后,我們可以使用這些模型上的pivot 屬性訪(fǎng)問(wèn)中間表字段:

 = User::find(1)-> (   ->pivot->role_id.'<br>'

 注意我們獲取到的每一個(gè) Role 模型都被自動(dòng)賦上了 pivot 屬性。該屬性包含一個(gè)代表中間表的模型,并且可以像其它 Eloquent 模型一樣使用。

默認(rèn)情況下,只有模型主鍵才能用在 pivot 對(duì)象上,如果你的 pivot 表包含額外的屬性,必須在定義關(guān)聯(lián)關(guān)系時(shí)進(jìn)行指定:

return $this->belongsToMany('App\Models\Role')->withPivot('column1', 'column2');

比如我們修改role_user表增加一個(gè)字段 username 數(shù)據(jù)如下:
平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

修改模型User:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

<?php

namespace App\Models;use Illuminate\Database\Eloquent\Model;/**
 * Class User
 * @package App\Models
 * @mixin \Eloquent */class User extends Model
{    /**
     * 用戶(hù)角色     */
    public function roles()
    {        //return $this->belongsToMany('App\Models\Role');
        return $this->belongsToMany('App\Models\Role')->withPivot('username');
    }
}

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 測(cè)試代碼如下:

 = User::find(1 (->roles   ->pivot->

如果你想要你的 pivot 表自動(dòng)包含created_at 和 updated_at 時(shí)間戳,在關(guān)聯(lián)關(guān)系定義時(shí)使用 withTimestamps 方法:

return $this->belongsToMany('App\Models\Role')->withTimestamps();

 通過(guò)中間表字段過(guò)濾關(guān)聯(lián)關(guān)系

你還可以在定義關(guān)聯(lián)關(guān)系的時(shí)候使用 wherePivot 和 wherePivotIn 方法過(guò)濾belongsToMany 返回的結(jié)果集:

return $this->belongsToMany('App\Models\Role')->withPivot('username')->wherePivot('username', '馬特2');
//return $this->belongsToMany('App\Models\Role')->wherePivotIn('role_id', [1, 2]);

測(cè)試代碼如下:

$user = User::find(1);print_r($user->roles->toArray());

以上對(duì)應(yīng)輸出:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

Array
(
    [0] => Array
        (
            [id] => 3
            [name] => 軍長(zhǎng)
            [created_at] => 2017-06-14 10:38:57
            [updated_at] => 2017-06-15 10:39:01
            [pivot] => Array
                (
                    [user_id] => 1
                    [role_id] => 3
                    [username] => 馬特2
                )

        )

)

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

如果你想要你的pivot表自動(dòng)包含created_atupdated_at時(shí)間戳,在關(guān)聯(lián)關(guān)系定義時(shí)使用withTimestamps方法:

return $this->belongsToMany('App\Models\Role')->withTimestamps();

這一節(jié)我先講到這里啦,下一節(jié)我將討論更復(fù)雜的三種關(guān)聯(lián)關(guān)系及其在模型中的定義及使用。未完待續(xù)...

無(wú)論從事什么行業(yè),只要做好兩件事就夠了,一個(gè)是你的專(zhuān)業(yè)、一個(gè)是你的人品,專(zhuān)業(yè)決定了你的存在,人品決定了你的人脈,剩下的就是堅(jiān)持,用善良專(zhuān)業(yè)和真誠(chéng)贏取更多的信任。不忘初心 方得始終!

分類(lèi): Laravel筆跡

數(shù)據(jù)表之間是縱橫交叉、相互關(guān)聯(lián)的,laravel的一對(duì)一,一對(duì)多比較好理解,官網(wǎng)介紹滴很詳細(xì)了,在此我就不贅述啦,重點(diǎn)我記下多對(duì)多的關(guān)系

一種常見(jiàn)的關(guān)聯(lián)關(guān)系是多對(duì)多,即表A的某條記錄通過(guò)中間表C與表B的多條記錄關(guān)聯(lián),反之亦然。比如一個(gè)用戶(hù)有多種角色,反之一個(gè)角色對(duì)應(yīng)多個(gè)用戶(hù)。

為了測(cè)試該關(guān)聯(lián)關(guān)系,我們沿用官網(wǎng)的用戶(hù)角色示例:

需要三張數(shù)據(jù)表:users、roles 和 role_user,role_user 表按照關(guān)聯(lián)模型名的字母順序命名(這里role_user是中間表),并且包含 user_id 和 role_id兩個(gè)列。

多對(duì)多關(guān)聯(lián)通過(guò)編寫(xiě)返回 belongsToMany 方法返回結(jié)果的方法來(lái)定義。廢話(huà)不說(shuō)多,直接上數(shù)據(jù)結(jié)構(gòu):

1:創(chuàng)建一個(gè)角色表roles,并添加一些初始化數(shù)據(jù):

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'admin', 'admin@163.com', '$2y$10$J/yXqscucanrHAGZp9G6..Tu1Md.SOljX3M8WrHsUdrgat4zeSuhC', 'ilocXtjZJwhrmIdLG1cKOYegeCwQCkuyx1pYAOLuzY2PpScQFT5Ss7lBCi7i', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `users` VALUES ('2', 'baidu', '10940370@qq.com', '$2y$10$2A5zJ4pnJ5uCp1DN3NX.5uj/Ap7P6O4nP2BaA55aFra8/rti1K6I2', null, '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `users` VALUES ('3', 'fantasy', '1009@qq.com', '', null, '2017-06-14 10:38:57', '2017-06-15 10:39:01');

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)


http://www.cnblogs.com/phpper/p/6950557.html