欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

[Laravel 5 教程学习笔记] 十四、Eloquent关系 有大用

shiping1 的头像

Eloquent关系基本可以分为:一对一、一对多及多对多。比如我们一个用户可以发表多篇文章,就是一对多的关系。这一节就是介绍 Laravel 5 中的Eloquent关系。

 

打开 app\User.php 用户模型,在 User 类中添加如下代码:


  1. public function articles(){

  2. return $this->hasMany('App\Article');

  3. }

这样就可以通过 $user->articles 来获取用户的所有文章了。现在来实现通过 $article->user 来获取文章所属的用户,打开 app\Article.php,在 Article 类中添加:


  1. public function user(){

  2. return $this->belongsTo('App\User');

  3. }

其中方法 user() 的名称可以自己随便定义,比如还可以叫 owner() 或者 writer() 等等。

现在还需要考虑我们的表结构,我们在表中还没有涉及到文章与用户的关联关系。现在打开之前我们创建的 migrations 文件 database\migrations\***_create_articles_table.php ,修改其中的up() 方法:


  1. public function up()

  2. {

  3. Schema::create('articles', function(Blueprint $table)

  4. {

  5. $table->increments('id');

  6. // 指定文章所属用户ID

  7. $table->integer('user_id')->unsigned();

  8. $table->string('title');

  9. $table->text('body');

  10. $table->timestamps();

  11. $table->timestamp('published_at');

  12.  

  13. // 生成外键,并且指定在删除用户时同时删除该用户的所有文章

  14. $table->foreign('user_id')

  15. ->references('id')

  16. ->on('users')

  17. ->onDelete('cascade');

  18. });

  19. }

$table->foreign('user_id')
      ->references('id')->on('users')
      ->onUpdate('cascade');

上面的方法中,添加了指定文章所属用户的字段 user_id ,指定其为用户表 users 的外键,并且当用户表中该用户被删除的时候,同时删除该用户的所有文章。

因为是本地开发环境,所以我们直接执行回滚操作,更新数据表结构。切记在线上的环境一定不要这么做,可以创建一个新的 migration 来完成该操作。

在命令行执行下面的命令:


  1. D:\wamp\www\laravel5>php artisan migrate:refresh

  2.  

  3. Rolled back: 2015_05_11_142009_add_excerpt_to_articles_table

  4. Rolled back: 2015_05_11_140813_create_articles_table

  5. Rolled back: 2014_10_12_100000_create_password_resets_table

  6. Rolled back: 2014_10_12_000000_create_users_table

  7. Nothing to rollback.

  8. Migrated: 2014_10_12_000000_create_users_table

  9. Migrated: 2014_10_12_100000_create_password_resets_table

  10. Migrated: 2015_05_11_140813_create_articles_table

  11. Migrated: 2015_05_11_142009_add_excerpt_to_articles_table

现在来创建用户,虽然Laravel 5为我们提供了一套现成的用户系统,但是我们这里还是使用命令行 tinker 来完成。


  1. D:\wamp\www\laravel5>php artisan tinker

  2. Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman

  3. >>> $user = new App\User;

  4. => <App\User #000000003bd871c8000000000acd1f5b> {}

  5. >>> $user->name = 'Specs';

  6. => "Specs"

  7. >>> $user->email = 'specs@example.com';

  8. => "specs@example.com"

  9. >>> $user->password = bcrypt('password');

  10. => "$2y$10$psEuDj9D81ZnNs083E7W9.SqvcEuLoAk4V5NuuDPC/xc.fU.1NMFq"

  11. >>> $user->save();

  12. => true

  13. >>> App\User::first()->toArray();

  14. => [

  15. "id" => 1,

  16. "name" => "Specs",

  17. "email" => "specs@example.com",

  18. "created_at" => "2015-06-07 12:41:37",

  19. "updated_at" => "2015-06-07 12:41:37"

  20. ]

用户密码必须要进行加密操作,bcrypt() 方法也可以用 Hash::make() 来替代。现成已经成功创建了一个新的用户。

现在来完成添加文章时与用户的关联操作。我们可以在控制器的 store() 方法中实现,但是现在我们先直接通过表单的一个隐藏域来完成,这样做是不安全的,实际环境中不可以使用该方法,下一节再来修复此问题。

打开 resources\views\articles\_form.blade.php ,在最上面添加:


  1. {!! Form::hidden('user_id', 1) !!}

接着修改文章模型 Article.php,修改可填充字段:


  1. protected $fillable = [

  2. 'title',

  3. 'body',

  4. 'published_at',

  5. 'user_id'

  6. ];

这时浏览器中发布一篇新的文章试试。发布之后到命令行执行:


  1. D:\wamp\www\laravel5>php artisan tinker

  2. Psy Shell v0.4.1 (PHP 5.5.12 ΓÇö cli) by Justin Hileman

  3. >>> App\Article::first()->toArray();

  4. => [

  5. "id" => 1,

  6. "user_id" => 1,

  7. "title" => "New Article",

  8. "body" => "This is a new article",

  9. "created_at" => "2015-06-07 12:52:02",

  10. "updated_at" => "2015-06-07 12:52:02",

  11. "published_at" => "2015-06-07 00:00:00",

  12. "excerpt" => null

  13. ]

  14.  

  15. // 获取第一个用户所有文章

  16. >>> $user = App\User::first();

  17. => <App\User #0000000070d8f2d5000000001310ee1c> {

  18. id: 1,

  19. name: "Specs",

  20. email: "specs@example.com",

  21. created_at: "2015-06-07 12:41:37",

  22. updated_at: "2015-06-07 12:41:37"

  23. }

  24. >>> $user->articles->toArray();

  25. => [

  26. [

  27. "id" => 1,

  28. "user_id" => 1,

  29. "title" => "New Article",

  30. "body" => "This is a new article",

  31. "created_at" => "2015-06-07 12:52:02",

  32. "updated_at" => "2015-06-07 12:52:02",

  33. "published_at" => "2015-06-07 00:00:00",

  34. "excerpt" => null

  35. ]

  36. ]

此外:


  1. >>> $user->articles();

  2. // 返回一个一对多的Object

  3. => <Illuminate\Database\Eloquent\Relations\HasMany #0000000070d8f2ca000000001310ee1c> {}

  4. >>> $user->articles->toArray();

  5. // 返回的是一个 collection

  6. => [

  7. [

  8. "id" => 1,

  9. "user_id" => 1,

  10. "title" => "New Article",

  11. "body" => "This is a new article",

  12. "created_at" => "2015-06-07 12:52:02",

  13. "updated_at" => "2015-06-07 12:52:02",

  14. "published_at" => "2015-06-07 00:00:00",

  15. "excerpt" => null

  16. ]

  17. ]

  18. //注意 使用 $user->articles 与 $user->articles() 的区别

  19. >>> $user->articles()->get()->toArray();

  20. => [

  21. [

  22. "id" => 1,

  23. "user_id" => 1,

  24. "title" => "New Article",

  25. "body" => "This is a new article",

  26. "created_at" => "2015-06-07 12:52:02",

  27. "updated_at" => "2015-06-07 12:52:02",

  28. "published_at" => "2015-06-07 00:00:00",

  29. "excerpt" => null

  30. ]

  31. ]

  32. // $user->articles() 可以添加查询条件,而$user->articles 则不能这么使用

  33. >>> $user->articles()->where('title', 'New Article')->get()->toArray();

  34. => [

  35. [

  36. "id" => 1,

  37. "user_id" => 1,

  38. "title" => "New Article",

  39. "body" => "This is a new article",

  40. "created_at" => "2015-06-07 12:52:02",

  41. "updated_at" => "2015-06-07 12:52:02",

  42. "published_at" => "2015-06-07 00:00:00",

  43. "excerpt" => null

  44. ]

  45. ]

上面通过用户获取了用户的所有文章,下面我们完成相反的操作,根据文章来获取用户信息。


  1. >>> $article = App\Article::first();

  2. => <App\Article #0000000073aaf26b000000001e78f0ec> {

  3. id: 1,

  4. user_id: 1,

  5. title: "New Article",

  6. body: "This is a new article",

  7. created_at: "2015-06-07 12:52:02",

  8. updated_at: "2015-06-07 12:52:02",

  9. published_at: "2015-06-07 00:00:00",

  10. excerpt: null

  11. }

  12. >>> $article->user->toArray();

  13. => [

  14. "id" => 1,

  15. "name" => "Specs",

  16. "email" => "specs@example.com",

  17. "created_at" => "2015-06-07 12:41:37",

  18. "updated_at" => "2015-06-07 12:41:37"

  19. ]

现在假设我们的显示某个用户所有文章的 URL 为 http://laravel.dev/user/Specs/articles,在命令行演示则为:


  1. >>> $user = App\User::where('name', 'Specs')->first();

  2. => <App\User #0000000073aaf264000000001e78f0ec> {

  3. id: 1,

  4. name: "Specs",

  5. email: "specs@example.com",

  6. created_at: "2015-06-07 12:41:37",

  7. updated_at: "2015-06-07 12:41:37"

  8. }

  9. >>> $articles = $user->articles->toArray();

  10. => [

  11. [

  12. "id" => 1,

  13. "user_id" => 1,

  14. "title" => "New Article",

  15. "body" => "This is a new article",

  16. "created_at" => "2015-06-07 12:52:02",

  17. "updated_at" => "2015-06-07 12:52:02",

  18. "published_at" => "2015-06-07 00:00:00",

  19. "excerpt" => null

  20. ]

  21. ]

  22. // 把获取的数据返回给视图:return view('articles.index', compact('articles'));

本节关于Eloquent关系就到这里。


 
 
转载请注明来源:[Laravel 5 教程学习笔记] 十四、Eloquent关系 - Specs' Blog-就爱PHP

本文共 1 个回复


普通分类: