Heim > Backend-Entwicklung > PHP-Tutorial > Eine häufige Beziehung in Laravel-Many-to-Many

Eine häufige Beziehung in Laravel-Many-to-Many

零下一度
Freigeben: 2023-03-10 16:38:02
Original
1580 Leute haben es durchsucht

Die Eins-zu-Eins- und Eins-zu-Viele-Datentabellen von Laravel sind sehr detailliert, daher werde ich hier nicht auf Details eingehen Viele-zu-viele-Punkte-Beziehung

Eine gemeinsame Assoziationsbeziehung ist viele-zu-viele, das heißt, ein Datensatz in Tabelle A ist über die Zwischentabelle C mit mehreren Datensätzen in Tabelle B verknüpft umgekehrt. Beispielsweise hat ein Benutzer mehrere Rollen und umgekehrt entspricht eine Rolle mehreren Benutzern.

Um diese Zuordnung zu testen, folgen wir dem Benutzerrollenbeispiel auf der offiziellen Website:

erfordert drei Datentabellen: users, roles und role_user, und das role_user Tabelle basiert auf der Zuordnung. Der Modellname wird in alphabetischer Reihenfolge benannt (hier ist Role_user die Zwischentabelle) und enthält zwei Spalten user_id und role_id.

Many-to-many-Beziehungen werden durch das Schreiben von Methoden definiert, die die von der belongsToMany-Methode zurückgegebenen Ergebnisse zurückgeben. Kommen wir ohne weiteres zur Datenstruktur:

1: Erstellen Sie eine Zeichentabelle roles und fügen Sie einige Initialisierungsdaten hinzu:

SET FOREIGN_KEY_CHECKS=0;

------------------------------
-- Tabellenstruktur für Benutzer
-- -- -- ------------------------
TABELLE LÖSCHEN, WENN „Benutzer“ EXISTIERT;
TABELLE „Benutzer“ ERSTELLEN (
` 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` Zeitstempel 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;

--------------------------------
-- Aufzeichnungen von Benutzern
---------------------------------------------
INSERT INTO `users` VALUES ('1', 'admin', 'admin@163.com', '$2y$10$J/yXqscucanrHAGZp9G6..Tu1Md.SOljX3M8WrHsUdrgat4zeSuhC', 'ilocXtjZJwhrmIdLG1cKOYegeCwQCkuyx1pYAOLuzY2PpScQFT5Ss7lBCi7i', '20 16 -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');

2 : Erstellen Sie eine Zeichentabelle roles und fügen Sie einige Initialisierungsdaten hinzu:

SET FOREIGN_KEY_CHECKS=0;

-- ------------- ----- ----------
-- Tabellenstruktur für Rollen
-- --------------------- ----- --
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;

------------- ----- ------------
-- Aufzeichnungen von Rollen
---------------------- -- ---
INSERT INTO `roles` VALUES ('1', 'Super Moderator', '2016-04-21 16:26:23', '2016-12-14 09:29:59') ;
INSERT INTO `roles` VALUES ('2', 'Commander', '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `roles` VALUES ('3', 'Army Commander', '2017-06-14 10:38:57', '2017-06-15 10:39:01');
INSERT INTO `roles` VALUES ('4', 'Director', '2017-06-07 10:41:41', '2017-06-15 10:41:51');
INSERT INTO `roles` VALUES ('5' , 'Teamkampf', '22.06.2017 10:41:44', '28.06.2017 10:41:54');
INSERT INTO `roles` VALUES ('6', '小兵' , '2017-06-22 10:41:47', '2017-06-22 10:41:56');

3: Erstellen Sie eine Zwischentabelle role_user für die Aufzeichnung-Tabelle und der users-Tabelle und fügen Sie einige Initialisierungsdaten hinzu: roles

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');
Nach dem Login kopieren
Beachten Sie, dass wir beim Definieren der Zwischentabelle keine s hinzufügen Das Ende und die Benennungsregeln lauten wie folgt. Stellen Sie in alphabetischer Reihenfolge die Rolle vorne und den Benutzer hinten ein und trennen Sie sie durch _. Dies alles dient der Anpassung an die Standardeinstellungen der Eloquent-Modellzuordnung: wenn keine Zwischentabelle angegeben ist Beim Definieren einer Viele-zu-Viele-Assoziation verwendet Eloquent standardmäßig die Zwischentabelle, um diese Regel zu spleißen.

Erstellen Sie ein

Modell: Role

<?php

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


}
Nach dem Login kopieren

然后我们在 User 模型上定义 roles 方法:

<?php

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

注:正如我们上面提到的,如果中间表不是role_user,那么需要将中间表作为第二个参数传入belongsToMany方法,如果中间表中的字段不是user_idrole_id,这里我们姑且将其命名为$user_id$role_id,那么需要将$user_id作为第三个参数传入该方法,$role_id作为第四个参数传入该方法,如果关联方法名不是roles还可以将对应的关联方法名作为第五个参数传入该方法。

接下来我们在控制器中编写测试代码:

<? = User::find(1 = -> '用户'.->name.'所拥有的角色:'(   ->name.'  '; //对应输出为:用户admin所拥有的角色:司令  军长  团战
Nach dem Login kopieren

 当然,和所有其它关联关系类型一样,你可以调用roles 方法来添加条件约束到关联查询上:

User::find(1)->roles()->orderBy('name')->get();
Nach dem Login kopieren

正如前面所提到的,为了确定关联关系连接表的表名,Eloquent 以字母顺序连接两个关联模型的名字。不过,你可以重写这种约定 —— 通过传递第二个参数到 belongsToMany 方法:

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

除了自定义连接表的表名,你还可以通过传递额外参数到 belongsToMany 方法来自定义该表中字段的列名。第三个参数是你定义关联关系模型的外键名称,第四个参数你要连接到的模型的外键名称:

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

定义相对的关联关系

要定义与多对多关联相对的关联关系,只需在关联模型中调用一下 belongsToMany 方法即可。我们在 Role 模型中定义 users 方法:

<?php

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

}
Nach dem Login kopieren

 正如你所看到的,定义的关联关系和与其对应的User 中定义的一模一样,只是前者引用 App\Models\Role,后者引用App\Models\User,由于我们再次使用了 belongsToMany 方法,所有的常用表和键自定义选项在定义与多对多相对的关联关系时都是可用的。

测试代码如下:

 = Role::find(2 = -> '角色#'.->name.'下面的用户:' (   ->name.' '
Nach dem Login kopieren

正如你看到的,处理多对多关联要求一个中间表。Eloquent 提供了一些有用的方法来与这个中间表进行交互,例如,我们假设 User 对象有很多与之关联的 Role 对象,访问这些关联关系之后,我们可以使用这些模型上的pivot 属性访问中间表字段:

 = User::find(1)-> (   ->pivot->role_id.'<br>'
Nach dem Login kopieren

 注意我们获取到的每一个 Role 模型都被自动赋上了 pivot 属性。该属性包含一个代表中间表的模型,并且可以像其它 Eloquent 模型一样使用。

默认情况下,只有模型主键才能用在 pivot 对象上,如果你的 pivot 表包含额外的属性,必须在定义关联关系时进行指定:

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

比如我们修改role_user表增加一个字段 username 数据如下:

修改模型User:

<?php

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

 测试代码如下:

 = User::find(1 (->roles   ->pivot->
Nach dem Login kopieren

如果你想要你的 pivot 表自动包含created_at 和 updated_at 时间戳,在关联关系定义时使用 withTimestamps 方法:

return $this->belongsToMany('App\Models\Role')->withTimestamps();
Nach dem Login kopieren
Nach dem Login kopieren

 通过中间表字段过滤关联关系

你还可以在定义关联关系的时候使用 wherePivot 和 wherePivotIn 方法过滤belongsToMany 返回的结果集:

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

测试代码如下:

$user = User::find(1);print_r($user->roles->toArray());
Nach dem Login kopieren

以上对应输出:

Array
(
    [0] => Array
        (
            [id] => 3[name] => 军长
            [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
                )

        )

)
Nach dem Login kopieren

如果你想要你的pivot表自动包含created_atupdated_at时间戳,在关联关系定义时使用withTimestamps方法:

return $this->belongsToMany('App\Models\Role')->withTimestamps();
Nach dem Login kopieren
Nach dem Login kopieren

这一节我先讲到这里啦,下一节我将讨论更复杂的三种关联关系及其在模型中的定义及使用。未完待续...

Das obige ist der detaillierte Inhalt vonEine häufige Beziehung in Laravel-Many-to-Many. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage