Php Laravel框架 多表关系管理 之 Eloquent一对多关系管理

        本博文主要介绍 Laravel 框架中 Eloquent
 对有些多关乎的拍卖以及在 Laravel
Administrator(后台扩大包)中的应用。

       
您的数据库恐怕是互为相关的。比如,一篇博客文章或者有大多评头论足,也许一个订单与下订单的用户相关。Eloquent
使得管理和管理这一个关系变得轻易。Laravel 提供了各类类型的关系: -一对一
-一对多 -多对多 – 多态关系

数据表之间是良莠不齐、互相关联的,laravel的一定,一对多比较好精晓,官方网站介绍滴很详细了,在此笔者就不赘述啦,注重我记下多对多的涉及

正文是本体系教程的完成篇,大家将协同给 Article
出席商酌成效,让游客在前台页面能够查阅、提交、回复商酌,并成功后台商量管理作用,可以去除、编辑商讨。Article
和商量将动用 Laravel Eloquent
提供的“一对多关系”作用大大简化模型间涉及的复杂度。最后,我们将获取一个私家博客系统的雏形,并计划一个大作业,供大家实战演练。

当今是二〇一七年四月5日,从伊始接触Laravel也会有小一年来了,那篇小说将记录自己利用Laravel的有个别新得。新的主张也将时刻更新到这篇作品中。

金沙注册送58,      一对多

一个一对多涉及的事例是一篇博客小说有过多议论纷繁也许二个课程有的数十次分数音信等。

一种常见的关联关系是多对多,即表A的某条记下通过中间表C与表B的多条记下关联,反之亦然。比如一个用户有三种剧中人物,反之一个剧中人物对应多个用户。

本篇小说中自己将会动用一些 Laravel
的尖端功效,那么些高档成效对菜鸟通晓系统是不利于的,但内行使用这么些意义能够大幅提高开辟效能。

1.目录外号

我们得以像这么定义关系模型 Model:

<?php /**  * sobjectinfo:课程信息表 Model  * soc_id     :主键自增  * soc_name   :课程名  * soc_teacher:授课老师  **/ class SobjectInfo extends Eloquent {     //自定义表名(protected $table)     protected $table = 'sobjectinfo';      //自定义主键(protected $primaryKey)     protected $primaryKey = 'soc_id';      //关闭 创建时间 与 更新时间 的自动维护(protected $timestamps)     public $timestamps = false;      /*      * 定义一对多关系      */     public function Scoreinfo(){         return $this -> hasMany('Scoreinfo','soc_id');     } }  ?>

为了测验该关联关系,大家沿用官方网站的用户剧中人物示例:

回顾 Eloquent

前边我们已经说过,Laravel Eloquent ORM 是 Laravel 中最强大的一部分,也是
Laravel
能这么流行最关键的从头到尾的经过。汉语文书档案在:

learnlaravel5/app/Article.php正是三个最简便的 Eloquent Model 类:

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Article extends Model{    //}

若想进一步询问 Eloquent 推荐阅读浩如烟海作品:深切明白 Laravel Eloquent

1.1说明

在ShenCom他们有一点点做的很好,便是把框架外的扩展全体放在了贰个单身的目录里面,未有去破坏Laravel框架自己的结构,让框架保持了本来的风味,又扩充了新的功用。

金沙注册送58 1

1-目录别称.png

概念与之相应的逆向关系 Model:

<?php /**  * scoreinfo:分数信息表 Model  * so_id   :主键自增  * s_id    :学生信息表(stuinfo)主键  * soc_id  :课程信息表(sobjectinfo)主键  * score   :分数  */ class ScoreInfo extends Eloquent {        //自定义表名(protected $table)        protected $table = 'scoreinfo';         //自定义主键(protected $primaryKey)        protected $primaryKey = 'so_id';         //关闭 创建时间 与 更新时间 的自动维护(protected $timestamps)        public $timestamps = false;         /*         * 分数表(ScoreInfo)与课程表(SobjectInfo)、学生信息表(StuInfo)有主外键关系         * 并且是一对多的关系         */         public function StuInfo(){             return $this -> belongsTo('StuInfo','s_id');         }          /*          * 定义逆向关系指向主键表          * */         public function SobjectInfo(){             return $this -> belongsTo('SobjectInfo','soc_id');         } }   ?>

通过上述步骤的管理,表与表之间的一对多涉及已确立,

亟需三张数据表:users、roles 和 role_user,role_user
表依照关联模型名的假名逐条命名(这里role_user是中间表),并且包含user_id 和 role_id两个列。

营造评论系统

1.2用法

上边将介绍在Laravel Administrato 后高雄的达成 下拉列表查询、绑定等利用

<?php  return array(      'title' => '分数信息',        //栏目名     'single' => ' >>',            //新建描述     'model' => 'ScoreInfo',       //分数信息     'form_width' => 960,          //左边栏目宽      //列表     'columns' => array(         'so_id' => array(             'title' => '编号',             'select' => "so_id",             'sort_field'=>'so_id'         ),         's_name'=>array(             'title'=>'学生姓名',             'relationship' => 'StuInfo',             'select' => '(:table).s_name',         ),        'soc_name'=>array(             'title'=>'课程名称',             'relationship' => 'SobjectInfo',             'select' => '(:table).soc_name',         ),         'score'=>array(             'title'=>'考试分数',             'select'=>'score'         ),     ),      //筛选信息     'filters' => array(         'so_id' => array(             'title'=>'编号'         ),         'SobjectInfo'=>array(             'type'    => 'relationship',             'title'   => '课程名'             'name_field' => 'soc_name',         ),         'StuInfo'=>array(             'type'  => 'relationship',             'title' => '学生姓名',             'name_field'  => 's_name',         ),         'score'=>array(             'title'=>'考试分数',             'type' => 'number'         ),      ),      //修改、新增     'edit_fields' => array(         'StuInfo'=>array(             'type'  => 'relationship',             'title' => '学生姓名',             'name_field'  => 's_name',         ),         'SobjectInfo'=>array(             'type'    => 'relationship',             'title'   => '课程名',             'name_field' => 'soc_name',         ),         'score'=>array(             'title'=>'考试分数',             'type'=>'text'         ),     )  );  ?>

上述示例显示的是 后台 分数消息 类。

示范中往往施用到
“学生姓名”、“课程名”,尽管她们存款和储蓄在分歧的表中,但由于大家事先在
Model中已创设了它们之间的 一对多关系,由此大家能够Infiniti制搭配组合

效率图如下:

金沙注册送58 2

金沙注册送58 3

多对多涉及通过编写制定重回 belongsToMany
方法重返结果的点子来定义。废话不说多,直接上数据结构:

基本功设计

我们必要新建多少个表特意用来存放在每一条商议,每一条商酌都属于某一篇作品。斟酌之间的层级关系相比复杂,本文为入门教程,首假使为着指引大家感受模型间涉及,就不再做过多的策动了,将“回复外人的评头品足”暂定为轻松的在评价内容后边扩充@johnlui那样的字符串。

1.2.1增多主服务文件

在 app\Providers\AppServiceProvider的boot方法中增添
App::register("\YaZhou\YaZhouServiceProvider");

11个Laravel4开荒职员必用扩大包:

1:创制一个剧中人物表roles,并加上一些开端化数据:

构建 Model 类和数据表

创建名称为 Comment 的 Model 类,并顺便成立附带的 migration,在
learnlaravel5 目录下运营命令:

php artisan make:model Comment -m

那样一次性建构了 Comment
类和learnlaravel5/database/migrations/2017_11_11_151823_create_comments_table.php三个文件。填充该文件的
up 方法,给comments表扩展字段:

public function up(){    Schema::create('comments', function (Blueprint $table) {        $table->increments('id');        $table->string('nickname');        $table->string->nullable();        $table->string('website')->nullable();        $table->text('content')->nullable();        $table->integer('article_id');        $table->timestamps;}

最契合中中原人民共和国人的,Eloquent一对多涉及处理。其后运维命令:

php artisan migrate

去数据库里看见,comments 表已经躺在那儿啦。

1.2.2起别名

compser.json个中扩展八个autoload选项。
试行命令composer dump-autpload

Laravel Administrator 文档

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');

树立“一对多涉及”

在 Article 模型中增添一对多关系的函数:

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Article extends Model{    public function hasManyComments()    {        return $this->hasMany('App\Comment', 'article_id', 'id');    }}

解决啦!Eloquent 中模型间关系便是那样轻松!

模型间关系粤语文书档案:
扩充阅读:深切了解 Laravel Eloquent——模型间关系

2.模型(Model)的定义

Laravel4 汉语补帮手册:

版权注明:本文为博主原创作品,未经博主允许不得转发。


2:创立二个剧中人物表roles,并丰盛一些起首化数据:

创设前台 UI

让大家修改前台的视图像和文字件,想艺术把商酌成效加进去。

2.1简短示例

namespace Yz\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Test extends Model{
    use SoftDeletes;

    protected   $primaryKey  =   "id";  
    protected   $table       =   "test";
    protected   $guarded     =   ["id"];
    public      $timestamps  =   false;
}
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', '超级版主', '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', '军长', '2017-06-14 10:38:57', '2017-06-15 10:39:01');
INSERT INTO `roles` VALUES ('4', '司长', '2017-06-07 10:41:41', '2017-06-15 10:41:51');
INSERT INTO `roles` VALUES ('5', '团战', '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');

创制前台的 ArticleController 类

运作命令:

php artisan make:controller ArticleController

日增路由:

Route::get('article/{id}', 'ArticleController@show');

此地的 {id} 指代任意字符串,在我们的计划中,此字段为小说ID,为数字,可是本行路由却会尝试相称全部央浼,所以当你遇上了不测的路由调用的措施跟你想像的不雷同期,记得检查路由逐个。路由格外方式为停放匹配:任何一条路由准绳相称成功,会马上回去结果,后边的路由便未有了响应的机缘。

给 ArticleController 增加 show 函数:

public function show($id){    return view('article/show')->withArticle(Article::with('hasManyComments')->find($id));}

别忘了在顶上部分引进 Model 类,不然会报类找不到的错误:

....use App\Article;class ArticleController extends Controller{....

2.2代码表明

protected $table
钦定当前模型对应的多少表名。
protected $primaryKey
钦命当前数据表的主键,暗中同意id。
public $timestamps
暗中同意境况下,Eloquent期望created_at和updated_at已经存在于数据表中,假让你不想要那么些Laravel自动管理的列,在模型类中设置$timestamps属性为false。
protected $guarded/$fillale
在运用create方法保存贰个新的模申时,全体的Eloquent模型都经过批量赋值(Mass
Assignment)举行保险,需求钦点模型的fillableguarded质量。在fillable里面包车型大巴都以足以被赋值的(白名单),在guarded里面包车型大巴都是不可以被赋值的(黑名单),fillable和guarded二选一。
use SoftDeletes
软删除,需要数据表中以三个字段“deleted_at”。被软删除的笔录并从未被真正的删减,只是在“deleted_at”字段记录了操作时间。
Model::withTrashed()->...,同时获得被软删除的笔录。
Model::onlyTrashed()->...,只获得被软删除的笔录。
$record->restore();,恢复生机被软删除的笔录。
$record->forceDelete(),强制删除。
$record-> history() -> forceDelete(),强制删除全体关模型。

3:成立一其中路表role_user用于记录users表与roles表的附和关系,并丰富一些开首化数据:

创制前台作品呈现视图

新建learnlaravel5/resources/views/article/show.blade.php文件:

<!DOCTYPE html><html lang="en"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>Learn Laravel 5</title>    <link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">    <script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>    <script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script></head>    <div  style="padding: 50px;">        <h4>            <a href="/"><< 返回首页</a>        </h4>        <h1 style="text-align: center; margin-top: 50px;">{{ $article->title }}</h1>        <hr>        <div  style="text-align: right;">            {{ $article->updated_at }}        </div>        <div  style="margin: 20px;">            <p>                {{ $article->body }}            </p>        </div>        <div  style="margin-top: 50px;">            @if (count($errors) > 0)                <div class="alert alert-danger">                    <strong>操作失败</strong> 输入不符合要求<br><br>                    {!! implode('<br>', $errors->all !!}                </div>            @endif            <div >                <form action="{{ url('comment') }}" method="POST">                    {!! csrf_field() !!}                    <input type="hidden" name="article_id" value="{{ $article->id }}">                    <div class="form-group">                        <label>Nickname</label>                        <input type="text" name="nickname" class="form-control" style="width: 300px;" required="required">                    </div>                    <div class="form-group">                        <label>Email address</label>                        <input type="email" name="email" class="form-control" style="width: 300px;">                    </div>                    <div class="form-group">                        <label>Home page</label>                        <input type="text" name="website" class="form-control" style="width: 300px;">                    </div>                    <div class="form-group">                        <label>Content</label>                        <textarea name="content"  class="form-control" rows="10" required="required"></textarea></div><button type="submit" class="btn btn-lg btn-success col-lg-12">Submit</button></form></div><script>function reply {var nickname = a.parentNode.parentNode.firstChild.nextSibling.getAttribute('data');var textArea = document.getElementById('newFormContent');textArea.innerHTML = '@'+nickname+' ';            }</script><div class="conmments" style="margin-top: 100px;">@foreach ($article->hasManyComments as $comment)<div class="one" style="border-top: solid 20px #efefef; padding: 5px 20px;"><div class="nickname" data="{{ $comment->nickname }}">@if ($comment->website)<a href="{{ $comment->website }}"><h3>{{ $comment->nickname }}</h3></a>@else<h3>{{ $comment->nickname }}</h3>@endif<h6>{{ $comment->created_at }}</h6></div><div class="content"><p style="padding: 20px;">                                {{ $comment->content }}</p></div><div class="reply" style="text-align: right; padding: 5px;"><a href="#new" onclick="reply;">回复</a></div></div>@endforeach</div></div></div></body></html>

2.3扩展

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');

营造探究存款和储蓄作用

大家须要创立一个 CommentsController
调节器,并扩展一条“存储商议”的路由。运维命令:

php artisan make:controller CommentController

调节器创设成功,接下去大家扩张一条路由:

Route::post('comment', 'CommentController@store');

给这么些类扩展 store 函数:

public function store(Request $request){    if (Comment::create($request->all {        return redirect()->back();    } else {        return redirect()->back()->withInput()->withErrors('评论发表失败!');    }}

这里 Comment 类请本身引进。

询问功用域

功能域允许你定义四个查询条件的通用集合,这样就足以在行使中有益地复用。详细情况参见,Laravel5.1汉语文书档案。

小心我们定义中间表的时候未有在结尾加s并且命名法规是遵照字母表顺序,将role放在日前,user放在前面,并且用_相隔,这一切都以为了适应Eloquent模型关联的暗许设置:在概念多对多关系的时候若无一些名中间表,Eloquent暗许的中间表使用这种法则拼接出来。

批量赋值

大家应用批量赋值方法来压缩存款和储蓄商量的代码,批量赋值汉语文书档案。

给 Comment 类增添 $fillable 成员变量:

protected $fillable = ['nickname', 'email', 'website', 'content', 'article_id'];

3.模型关系

创办四个Role模型:

反省成果

前台文章显示页:

金沙注册送58 4

交付几条商议之后:

金沙注册送58 5

恭喜你,前台研商作用创设产生!

3.1一对一涉及

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

营造后台批评管理成效

评说跟 阿特icle 同样,是一种能够管理的能源列表。二〇一四版教程的尾声,作者十万火急地罗列了一批又一群的代码,其实对还没入门的人差不离没用。在此,作者将这一个效果作为大作业安顿给大家。大作业嘛,当然是绝非标准答案的,但管用果图:

金沙注册送58 6

金沙注册送58 7

在做那几个大作业的历程中,你将会一再地回头去看这两天的教程,每每地阅读汉语文书档案,会细心阅读小编的代码,等您完了大作业的时候,Laravel
就真正入门啦~~

转发她处,侵犯版权联系删除

3.1.1关联的定义
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model{
    //  获取关联到用户的手机
    public function phone(){
        return $this->hasOne("Yz\Test\Models\Phone");
        // 这种写法默认Phone模型中有一个user_id外键,默认与当前模型的id关联

        // return $this->hasOne("Yz\Test\Models\Phone", "user_id");
        // 指定Phone模型中的外键,默认与当前模型的id关联

        // return $this->hasOne("Yz\Test\Models\Phone", "user_id", "id");
        // 指定phone模型的外键,同时指定当前模型的关联键,推荐使用
    }
}

然后大家在 User 模型上定义 roles 方法:

3.1.2定义关系的相持关联
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Phone extends Model{
    public function user(){
        // 找到电话所属的用户
        return $this->belongsTo("Yz\Test\Models\User");
        // 默认通过当前表的user_id去匹配user表的id

        // return $this->belongsTo("Yz\Test\Models\User", "user_id");
        // 指定当前表的关联字段,去与主表的id字段进行匹配

        // return $this->belongsTo("Yz\Test\Models\User", "user_id", "id");
        // 指定当前表的user_id与User表的id进行匹配,推荐使用
    }
}
<?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');
  }
}
3.1.3一对一关联的接纳

$phone = User::find(1)->phone;

注:正如咱们地方提到的,假设中间表不是role_user,那么须求将中间表作为第三个参数字传送入belongsToMany方法,假如中间表中的字段不是user_id和role_id,这里大家姑且将其命名称叫$user_id和$role_id,那么需求将$user_id作为第1个参数传入该格局,$role_id作为第多少个参数字传送入该措施,假设提到方法名不是roles还足以将相应的涉及方法名作为第四个参数字传送入该办法。

3.2 一对多关系

接下去大家在调整器中编辑测量检验代码:

3.2.1关系的定义
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model{
    /*博客数据*/

    public function comments(){
        // 获取博客的评论
        return $this->hasMany("Yz\Test\Models\Comment");

        // $this->hasMany("Yz\Test\Models\Comment", "post_id");
        // $this->hasMany("Yz\Test\Models\Comment", "post_id", "id");
    }
}
<?php
$user = User::find(1);
$roles = $user->roles;
echo '用户'.$user->name.'所拥有的角色:';
foreach($roles as $role)
  echo $role->name.' '; //对应输出为:用户admin所拥有的角色:司令 军长 团战 
3.2.2定义关系的相对关联
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model{
    /*博客的评论*/

    public function post(){
        return $this->belongsTo("Yz\Test\Models\Post");

        // return $this->belongsTo("Yz\Test\Models\Post", "post_id");
        // return $this->belongsTo("Yz\Test\Models\Post", "post_id", "id");
    }
}

自然,和全部其余关联关系项目同样,你能够调用roles
方法来增加条件约束到事关查询上:

3.2.3一对多涉及的行使
$comments = App\Post::find(1)->comments;
$comments = App\Post::find(1)->comments()->where('title', 'foo')->first();

$comment = App\Comment::find(1);
echo $comment->post->title;
User::find(1)->roles()->orderBy('name')->get();

3.3多对多涉及

福寿齐天多对多关系须要三个中间表。比方,多个用户(user)具有三种剧中人物(role),那么大家就需求一个中间表(user_role)。

正如前方所关联的,为了明确关联关系连接表的表名,Eloquent
以字母逐个而再接七个涉及模型的名字。不过,你能够重写这种约定 ——
通过传递首个参数到 belongsToMany 方法:

3.3.1关乎的概念
public function roles(){
        return $this->belongsToMany("Yz\Test\Model\Role");
        // 省略写法,要求中间表的名字为role_user,且中间表包含role_id和user_id两个字段

        // return $this->belongsToMany("Yz\Test\Models\Role", "user_role");
        // 半完整写法

        // return $this->belongsToMany("Yz\Test\Models\Role", "user_role", "user_id", "role_id");
        // 完整写法
    }
return $this->belongsToMany('App\Models\Role', 'user_roles');
3.3.2概念关系的对峙关联
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    // 用户角色

    public function users()
    {
        // 找到属于当前角色的用户
        return $this->belongsToMany("Yz\Test\Models\User");

        // return $this->belongsToMany("Yz\Test\Models\User", "user_role");
        // return $this->belongsToMany("Yz\Test\Models\User", "user_role", "role_id", "user_id");
    }
}

除去自定义连接表的表名,你还足以因而传递额外参数到 belongsToMany
方法来自定义该表中字段的列名。第多个参数是您定义关联关系模型的外键名称,第多少个参数你要连接到的模子的外键名称:

3.3.3多对多涉及的行使
$user = App\User::find(1);
foreach ($user->roles as $role) {
    //
}

$roles = App\User::find(1)->roles()->orderBy('name')->get();
return $this->belongsToMany('App\Models\Role', 'user_roles', 'user_id', 'role_id');

3.4插加入关贸总协定组织联模型

概念相对的关系关系

3.4.1插入一个关联模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$comment = $post->comments()->save($comment);

要定义与多对多关系相对的涉及关系,只需在事关模型中调用一下 belongsToMany
方法就可以。大家在 Role 模型中定义 users 方法:

3.4.2插入多少个事关模型
$post = App\Post::find(1);
$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);

除了那些之外save和saveMany方法外,仍是可以够应用create方法,该办法接收属性数组、创造模型、然后插入数据库。save和create的分化之处在于save接收整个Eloquent模型实例而create接收原生PHP数组。

$post = App\Post::find(1);
$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);
<?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');
  }
}
3.4.3更新关联模型

履新belongsTo关联的时候,能够应用associate方法,该方法会在子模型设置外键。

$account = App\Account::find(10);
$user->account()->associate($account);
$user->save();

 正如您所见到的,定义的关联关系和与其对应的User
中定义的一模二样,只是前面七个引用App\Models\Role,后面一个引用App\Models\User,由于大家再一次使用了
belongsToMany
方法,全部的常用表和键自定义选项在概念与多对多相对的关系关系时都是可用的。

3.4.4移除关联模型

移除belongsTo关联的时候,能够运用dissociate方法。该方法在子模型上撤销外键和涉嫌。

$user->account()->dissociate();
$user->save();

测量试验代码如下:

3.4.5多对多关系的附加
$user = App\User::find(1);
$user->roles()->attach($roleId);

叠合关联关系到模型,还能以数组方式传递额外被插入数据到中间表:
$user->roles()->attach($roleId, ['expires' => $expires])

$role = Role::find(2);
$users = $role->users;
echo '角色#'.$role->name.'下面的用户:';
foreach ($users as $user) 
  echo $user->name.' ';//对应输出为:角色#司令下面的用户:admin fantasy baidu
3.4.6多对多关系的移除
// 从指定用户中移除角色...
$user->roles()->detach($roleId);
// 从指定用户移除所有角色...
$user->roles()->detach();

为了便于,attach和detach还吸收接纳数组情势的ID作为输入。

$user = App\User::find(1);
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);

正如您看看的,管理多对多涉及供给叁其中间表。Eloquent
提供了一部分灵光的章程来与这几个中间表进行互动,举个例子,我们倘若 User
对象有众多与之提到的 Role
对象,访问那么些涉嫌关系之后,大家能够运用那个模型上的pivot
属性访问中间表字段:

3.4.7触发父级时间戳

当多个模型属于此外三个时,比方Comment属于Post,子模型更新时父模型的年月戳也被更新将很有用,比方,当Comment模型被更新时,你大概想要”触发“成立其所属模型Post的updated_at时间戳。Eloquent使得那项操作变得轻松,只必要丰盛富含关联关系名称的touches属性到子模型中就能够。

$roles = User::find(1)->roles;
foreach ($roles as $role) 
  echo $role->pivot->role_id.'<br>';//对应输出为:2 3 5

在意大家获得到的每三个 Role 模型都被活动赋上了 pivot
属性。该属性包蕴三个意味中间表的模型,并且能够像任何 Eloquent
模型同样选拔。

暗中同意情状下,唯有模型主键本领用在 pivot 对象上,如若你的 pivot
表包涵额外的习性,必须在概念关联关系时打开点名:

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

比如我们修改role_user表扩大三个字段 username 数据如下:

金沙注册送58 8

修改模型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');
  }
}

 测量检验代码如下:

$user = User::find(1);
foreach ($user->roles as $role) 
  echo $role->pivot->username;//对应输出为:马特马特2马特3

借使您想要你的 pivot 表自动包蕴created_at 和 updated_at
时间戳,在涉及关系定义时利用 withTimestamps 方法:

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

由个中间表字段过滤关联关系

你还能在概念关联关系的时候利用 wherePivot 和 wherePivotIn
方法过滤belongsToMany 重返的结果集:

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

测量检验代码如下:

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

上述对应输出:

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
        )
    )
)

设若您想要你的pivot表自动包括created_at和updated_at时间戳,在事关关系定义时利用withTimestamps方法:

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

上述所述是小编给大家介绍的PHP
laravel中的多对多涉及实例详解,希望对大家有所帮忙,若是大家有任何疑问请给笔者留言,作者会及时恢复生机我们的。在此也特别多谢我们对台本之家网址的支撑!

你大概感兴趣的稿子:

  • PHP框架Laravel插件Pagination完毕自定义分页
  • PHP的Laravel框架中利用AdminLTE模板来编排网址后台分界面
  • 深远分析PHP的Laravel框架中的event事件操作
  • PHP的Laravel框架结合MySQL与Redis数据库的使用布署
  • PHP的Laravel框架中采纳新闻队列queue及异步队列的艺术
  • 详解PHP的Laravel框架中Eloquent对象关联映射使用
  • 到家解读PHP的人气开拓框架Laravel
  • Nginx中运作PHP框架Laravel的配置文件分享

相关文章

网站地图xml地图