Eloquent关系基本可以分为:一对一、一对多及多对多。比如我们一个用户可以发表多篇文章,就是一对多的关系。这一节就是介绍 Laravel 5 中的Eloquent关系。
打开 app\User.php 用户模型,在
User
类中添加如下代码:
- public function articles(){
- return $this->hasMany('App\Article');
- }
这样就可以通过
$user->articles
来获取用户的所有文章了。现在来实现通过 $article->user
来获取文章所属的用户,打开 app\Article.php,在 Article
类中添加:
- public function user(){
- return $this->belongsTo('App\User');
- }
其中方法
user()
的名称可以自己随便定义,比如还可以叫 owner()
或者 writer()
等等。
现在还需要考虑我们的表结构,我们在表中还没有涉及到文章与用户的关联关系。现在打开之前我们创建的 migrations 文件 database\migrations\***_create_articles_table.php ,修改其中的
up()
方法:
- public function up()
- {
- Schema::create('articles', function(Blueprint $table)
- {
- $table->increments('id');
- // 指定文章所属用户ID
- $table->integer('user_id')->unsigned();
- $table->string('title');
- $table->text('body');
- $table->timestamps();
- $table->timestamp('published_at');
- // 生成外键,并且指定在删除用户时同时删除该用户的所有文章
- $table->foreign('user_id')
- ->references('id')
- ->on('users')
- ->onDelete('cascade');
- });
- }
上面的方法中,添加了指定文章所属用户的字段
user_id
,指定其为用户表 users
的外键,并且当用户表中该用户被删除的时候,同时删除该用户的所有文章。
因为是本地开发环境,所以我们直接执行回滚操作,更新数据表结构。切记在线上的环境一定不要这么做,可以创建一个新的
migration
来完成该操作。
在命令行执行下面的命令:
- D:\wamp\www\laravel5>php artisan migrate:refresh
- Rolled back: 2015_05_11_142009_add_excerpt_to_articles_table
- Rolled back: 2015_05_11_140813_create_articles_table
- Rolled back: 2014_10_12_100000_create_password_resets_table
- Rolled back: 2014_10_12_000000_create_users_table
- Nothing to rollback.
- Migrated: 2014_10_12_000000_create_users_table
- Migrated: 2014_10_12_100000_create_password_resets_table
- Migrated: 2015_05_11_140813_create_articles_table
- Migrated: 2015_05_11_142009_add_excerpt_to_articles_table
现在来创建用户,虽然Laravel 5为我们提供了一套现成的用户系统,但是我们这里还是使用命令行 tinker 来完成。
- D:\wamp\www\laravel5>php artisan tinker
- Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman
- >>> $user = new App\User;
- => <App\User #000000003bd871c8000000000acd1f5b> {}
- >>> $user->name = 'Specs';
- => "Specs"
- >>> $user->email = 'specs@example.com';
- => "specs@example.com"
- >>> $user->password = bcrypt('password');
- => "$2y$10$psEuDj9D81ZnNs083E7W9.SqvcEuLoAk4V5NuuDPC/xc.fU.1NMFq"
- >>> $user->save();
- => true
- >>> App\User::first()->toArray();
- => [
- "id" => 1,
- "name" => "Specs",
- "email" => "specs@example.com",
- "created_at" => "2015-06-07 12:41:37",
- "updated_at" => "2015-06-07 12:41:37"
- ]
用户密码必须要进行加密操作,
bcrypt()
方法也可以用 Hash::make()
来替代。现成已经成功创建了一个新的用户。
现在来完成添加文章时与用户的关联操作。我们可以在控制器的
store()
方法中实现,但是现在我们先直接通过表单的一个隐藏域来完成,这样做是不安全的,实际环境中不可以使用该方法,下一节再来修复此问题。
打开 resources\views\articles\_form.blade.php ,在最上面添加:
- {!! Form::hidden('user_id', 1) !!}
接着修改文章模型 Article.php,修改可填充字段:
- protected $fillable = [
- 'title',
- 'body',
- 'published_at',
- 'user_id'
- ];
这时浏览器中发布一篇新的文章试试。发布之后到命令行执行:
- D:\wamp\www\laravel5>php artisan tinker
- Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman
- >>> App\Article::first()->toArray();
- => [
- "id" => 1,
- "user_id" => 1,
- "title" => "New Article",
- "body" => "This is a new article",
- "created_at" => "2015-06-07 12:52:02",
- "updated_at" => "2015-06-07 12:52:02",
- "published_at" => "2015-06-07 00:00:00",
- "excerpt" => null
- ]
- // 获取第一个用户所有文章
- >>> $user = App\User::first();
- => <App\User #0000000070d8f2d5000000001310ee1c> {
- id: 1,
- name: "Specs",
- email: "specs@example.com",
- created_at: "2015-06-07 12:41:37",
- updated_at: "2015-06-07 12:41:37"
- }
- >>> $user->articles->toArray();
- => [
- [
- "id" => 1,
- "user_id" => 1,
- "title" => "New Article",
- "body" => "This is a new article",
- "created_at" => "2015-06-07 12:52:02",
- "updated_at" => "2015-06-07 12:52:02",
- "published_at" => "2015-06-07 00:00:00",
- "excerpt" => null
- ]
- ]
此外:
- >>> $user->articles();
- // 返回一个一对多的Object
- => <Illuminate\Database\Eloquent\Relations\HasMany #0000000070d8f2ca000000001310ee1c> {}
- >>> $user->articles->toArray();
- // 返回的是一个 collection
- => [
- [
- "id" => 1,
- "user_id" => 1,
- "title" => "New Article",
- "body" => "This is a new article",
- "created_at" => "2015-06-07 12:52:02",
- "updated_at" => "2015-06-07 12:52:02",
- "published_at" => "2015-06-07 00:00:00",
- "excerpt" => null
- ]
- ]
- //注意 使用 $user->articles 与 $user->articles() 的区别
- >>> $user->articles()->get()->toArray();
- => [
- [
- "id" => 1,
- "user_id" => 1,
- "title" => "New Article",
- "body" => "This is a new article",
- "created_at" => "2015-06-07 12:52:02",
- "updated_at" => "2015-06-07 12:52:02",
- "published_at" => "2015-06-07 00:00:00",
- "excerpt" => null
- ]
- ]
- // $user->articles() 可以添加查询条件,而$user->articles 则不能这么使用
- >>> $user->articles()->where('title', 'New Article')->get()->toArray();
- => [
- [
- "id" => 1,
- "user_id" => 1,
- "title" => "New Article",
- "body" => "This is a new article",
- "created_at" => "2015-06-07 12:52:02",
- "updated_at" => "2015-06-07 12:52:02",
- "published_at" => "2015-06-07 00:00:00",
- "excerpt" => null
- ]
- ]
上面通过用户获取了用户的所有文章,下面我们完成相反的操作,根据文章来获取用户信息。
- >>> $article = App\Article::first();
- => <App\Article #0000000073aaf26b000000001e78f0ec> {
- id: 1,
- user_id: 1,
- title: "New Article",
- body: "This is a new article",
- created_at: "2015-06-07 12:52:02",
- updated_at: "2015-06-07 12:52:02",
- published_at: "2015-06-07 00:00:00",
- excerpt: null
- }
- >>> $article->user->toArray();
- => [
- "id" => 1,
- "name" => "Specs",
- "email" => "specs@example.com",
- "created_at" => "2015-06-07 12:41:37",
- "updated_at" => "2015-06-07 12:41:37"
- ]
现在假设我们的显示某个用户所有文章的 URL 为 http://laravel.dev/user/Specs/articles,在命令行演示则为:
- >>> $user = App\User::where('name', 'Specs')->first();
- => <App\User #0000000073aaf264000000001e78f0ec> {
- id: 1,
- name: "Specs",
- email: "specs@example.com",
- created_at: "2015-06-07 12:41:37",
- updated_at: "2015-06-07 12:41:37"
- }
- >>> $articles = $user->articles->toArray();
- => [
- [
- "id" => 1,
- "user_id" => 1,
- "title" => "New Article",
- "body" => "This is a new article",
- "created_at" => "2015-06-07 12:52:02",
- "updated_at" => "2015-06-07 12:52:02",
- "published_at" => "2015-06-07 00:00:00",
- "excerpt" => null
- ]
- ]
- // 把获取的数据返回给视图:return view('articles.index', compact('articles'));
本节关于Eloquent关系就到这里。
该篇属于专题:《Laravel 5 基础视频教程学习笔记》
from : http://9iphp.com/web/laravel/laravel-5-eloquent-relations.html
沒有留言:
張貼留言