laravel框架学习---Eloquent Relationship

        在开始正文之前,我们首先来说说在实际的开发中,经常会接触到几种常见的对应关系模式:

One-To-One   //一对一
One-To-Many  //一对多
Many-To-Many //多对多

        不知道你对这些概念是一种什么样的感受,如果是不太理解的。你可以将这些概念应用到生活中,理解起来就很简单了,就举一个与我们在网上经常见到的例子:

User-To-Profile // One-To-One
User-To-Articles // One-To-Many
Article-To-Comments // One-To-Many
Articles-To-Tags // Many-To-Many

        翻译过来就是:

        ①、一个用户对应一个用户档案

        ②、一个用户可以发表多篇文章

        ③、一篇文章可以有多个评论

        ④、而文章和标签确实多对多的关系,一篇文章可以有多个标签;一个标签可以属于多篇文章

        

        在这些关系模型中,最难实现的就是Many-To-Many这种多对多的关系,但是我们这个简单地博客并没有用户管理,也就是并没有开放让用户注册,所以我们在这里还是要挑战一下难度,实现Articles-To-Tags这种Many-To-Many关系,借助Laravel的强大的Eloquent,实现这个功能还是比较顺心的。至于一对一和一对多这两种关系,可以触类旁通。


        我们使用Laravel项目的artisan命令行工具先启动一下项目:

D:\software\wamp64\www\laravel5>php artisan serve

        还记得开始 的时候,我们创建了一个文章表( articles ),如图所示:

        冷暖自知一抹茶ck

        如果要想实现一对多,多对多的关系的话,我们需要修改 上述 up方法,添加两个字段:

public function up()
{
    Schema::create('articles', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();                //整型的user_id正整数
        $table->string('title');
        $table->text('content');
        $table->timestamp('published_at');
        $table->timestamps();
        $table->foreign('user_id')->references('id')->on('users');//user_id 是users表的外键
    });
}

        如果用这种形式重新去创建我们的articles表的话,就需要去执行命令:php artisan migrate:refresh

D:\software\wamp64\www\laravel5>php artisan migrate:refresh

        要注意的是:这种形式会把之前数据库中的数据全部给抹掉,亲测,泪~~~~

    

        所以这里介绍第二种方法:

        ①、恢复刚才的up方法。

        ②、执行命令:php artisan make:migration add_user_id_colum_to_articles --table=articles

D:\software\wamp64\www\laravel5>php artisan make:migration add_user_id_colum_to_articles --table=articles
Created Migration: 2018_07_25_151128_add_user_id_colum_to_articles

        打开,database\migrations\2018_07_25_151128_add_user_id_colum_to_articles.php 新生成的文件。修改 up 方法。

public function up()
{
    Schema::table('articles', function (Blueprint $table) {
        //
        $table->integer('user_id')->default(1);//给articles表添加一个user_id字段,默认当前所属文章都是users表id为1的文章
    });
}

        然后在命令行再执行命令:php artisan migrate

D:\software\wamp64\www\laravel5>php artisan migrate
Migrating: 2018_07_25_151128_add_user_id_colum_to_articles
Migrated:  2018_07_25_151128_add_user_id_colum_to_articles

        冷暖自知一抹茶ck

        通过数据库管理工具,查看我们的articles表的数据,可知,表已经修改成功,并且默认是 users 表 id为 1 的数据。

        冷暖自知一抹茶ck

      

        声明Eloquent的关系:

         articles表中有了user_id,我们的工作并没有完成,我们下一步需要做的就是 告诉laravel 这种关系是如何声明的。这个时候就需要来到我们的  User  model这个文件。app\User.php 这个文件是 laravel默认为我们生成的。

        修改 User.php ,添加方法:

public function articles()
{
    return $this->hasMany('App\Article'); //一个用户可以有多个文章
}

        这里要注意的是,如果 hasMany 的第二个参数名是,你的外键名是什么?如果 上述不是 user_id(laravel默认的),比如说是 user,就需要修改成:

public function articles()
{
    return $this->hasMany('App\Article'); 
}

      

         修改完成之后,来到我们的 Article model,这里我们会有一个相对应的方法;叫做

public function user()
{
       return $this->belongsTo('App\User');//一篇文章属于某一个用户的
}

        

        这样,我们就有了模型之间的 Eloquent Relationship,有了关系之后,我们就可以测试一下,看看到底怎么运行的。

D:\software\wamp64\www\laravel5>php artisan tinker
Psy Shell v0.9.6 (PHP 7.0.10 鈥?cli) by Justin Hilemann
>>> $user = App\User::first();
=> App\User {#2855
     id: 1,
     name: "ck",
     email: "a@a.com",
     created_at: "2018-07-25 14:51:50",
     updated_at: "2018-07-25 14:51:50",
   }
>>> $user->articles
=> Illuminate\Database\Eloquent\Collection {#2865
     all: [
       App\Article {#2866
         id: 3,
         title: "aaa",
         content: "aaaaaaaaaaa",
         published_at: "2018-07-12 16:24:46",
         created_at: "2018-07-12 16:24:46",
         updated_at: "2018-07-12 16:24:46",
         intro: "鎾板啓鏂版枃绔?,
         user_id: 1,
       },
       App\Article {#2867
         id: 2,
         title: "change title update",
         content: "second title update",
         published_at: "2018-07-23 16:53:17",
         created_at: "2018-07-08 16:09:32",
         updated_at: "2018-07-23 16:53:17",
         intro: "second intro",
         user_id: 1,
       },
       App\Article {#2868
         id: 4,
         title: "楂樹寒鏄剧ず鍏抽敭瀛?,
         content: "鑰屾垜鍗?,
         published_at: "2018-07-21 00:00:00",
         created_at: "2018-07-21 16:43:07",
         updated_at: "2018-07-21 16:43:07",
         intro: "鑰屾垜鍗?,
         user_id: 1,
       },
       App\Article {#2869
         id: 5,
         title: "22楂樹寒鏄剧ず鍏抽敭瀛?,
         content: "1",
         published_at: "2018-07-22 16:59:21",
         created_at: "2018-07-21 16:59:21",
         updated_at: "2018-07-21 16:59:21",
         intro: "1",
         user_id: 1,
       },
       App\Article {#2870
         id: 6,
         title: "111111111111",
         content: "1111111111111",
         published_at: "2018-07-22 15:44:01",
         created_at: "2018-07-22 15:44:01",
         updated_at: "2018-07-22 15:44:01",
         intro: "111111111111",
         user_id: 1,
       },
       App\Article {#2871
         id: 7,
         title: "1112222",
         content: "222",
         published_at: "2018-07-22 15:44:59",
         created_at: "2018-07-22 15:44:59",
         updated_at: "2018-07-22 15:44:59",
         intro: "222",
         user_id: 1,
       },
       App\Article {#2872
         id: 8,
         title: "3333",
         content: "3333",
         published_at: "2018-07-22 15:47:08",
         created_at: "2018-07-22 15:47:08",
         updated_at: "2018-07-22 15:47:08",
         intro: "333",
         user_id: 1,
       },
       App\Article {#2873
         id: 9,
         title: "5",
         content: "5",
         published_at: "2018-07-22 16:04:48",
         created_at: "2018-07-22 16:04:48",
         updated_at: "2018-07-22 16:04:48",
         intro: "5",
         user_id: 1,
       },
       App\Article {#2874
         id: 10,
         title: "123",
         content: "22222",
         published_at: "2018-07-22 16:05:14",
         created_at: "2018-07-22 16:05:14",
         updated_at: "2018-07-22 16:05:14",
         intro: "a'a",
         user_id: 1,
       },
       App\Article {#2875
         id: 11,
         title: "777",
         content: "777",
         published_at: "2018-07-22 16:09:05",
         created_at: "2018-07-22 16:09:05",
         updated_at: "2018-07-22 16:09:05",
         intro: "77",
         user_id: 1,
       },
     ],
   }
   }
>>>

        ①、我们先用 User 模型获取到了第一个用户;

        ②、用这个对象(用户),去获取到了他所有的文章,这里调用的$user->articles,  articles方法即是 我们 User模型中刚刚声明的 articles 方法 (这个方法名是可以随便改的)。

        

        同理,亦然,我们获取第一篇文章,然后执行 user 方法,就可以找到这篇文章所对应的 创建用户user

>>> $article = App\Article::first();
=> App\Article {#2860
     id: 3,
     title: "aaa",
     content: "aaaaaaaaaaa",
     published_at: "2018-07-12 16:24:46",
     created_at: "2018-07-12 16:24:46",
     updated_at: "2018-07-12 16:24:46",
     intro: "鎾板啓鏂版枃绔?,
     user_id: 1,
   }}
>>> $article->user
=> App\User {#2861
     id: 1,
     name: "ck",
     email: "a@a.com",
     created_at: "2018-07-25 14:51:50",
     updated_at: "2018-07-25 14:51:50",
   }
>>>
>>> $article->user->name
=> "ck"


        那么在实际当中,我们是怎么把这个关系映射到我们的文章发表当中呢?

        比如说一个简单的例子,我们来到  app\Http\Controllers\ArticlesController.php 控制器当中,这里演示下我们在创建我们文章的时候,如何将user_id 字段映射到我们的文章 articles 表。(修改store 方法)

        一旦我们是需要这种一对多的关系的话,我们就默认前提这个用户是登录进来,才可以发表我们的文章。所以这个时候,我们就可以直接将我们的user_id拿到了,然后合并我们的表单数据:

public function store(\App\Http\Requests\createArticleRequest $request)
{  
   Article::create(array_merge( ['user_id'=>\Auth::user()->id], $request->all()));
      return redirect('/articles');
}

        要注意的是:这个添加完之后,还需要修改 Article   模型:把user_id添加进去

protected $fillable = ['title','content','published_at','intro','user_id'];

         

        这个时候去 访问 http://127.0.0.1:8000/articles/create 文章添加页面,输入信息后,添加成功后就会跳转到文章列表页面。

        冷暖自知一抹茶ck冷暖自知一抹茶ck


        再次访问数据库,查看 新添加的文章,即可看到 user表 id为2的已经成功添加一条数据;

        冷暖自知一抹茶ck


冷暖自知一抹茶ck
请先登录后发表评论
  • 最新评论
  • 总共0条评论