欢迎各位兄弟 发布技术文章
这里的技术是共享的
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');
});
}
$table->foreign('user_id')
->references('id')->on('users')
->onUpdate('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 基础视频教程学习笔记》
本文共 1 个回复
hi_tp 2015/07/14 16:20
非常感谢能发布这一系列的教程