2017-06-17 45 views
0

我试图从表中检索数据,我没有从我目前使用的模型直接关系。如何在Laravel雄辩中建立三个表之间的关系?

我的数据结构:

表:帖子

  • ID - 整数
  • 标题 - 字符串

表:post_stacks

  • ID - 整数
  • POST_ID - 整数
  • stack_id - 整数

表:

  • ID - 整数
  • 体 - 字符串
  • 网址 - 串

我的口才模型是从post.php中(职位表),我试图让关联到我的帖子的所有堆栈(从栈表)。我只想在Post.php而不是我的数据透视表(post_stacks)上声明我的关系。

我试过hasManyThrough,但我的表结构不符合Laravel要求的需求,因为我需要在我的Stacks表上使用外键。

这是我目前的执行:

post.php中

class Post extends Model 
 
{ 
 

 
    protected $dates = [ 
 
     'created_at', 
 
     'updated_at' 
 
    ]; 
 

 
    public function user() 
 
    { 
 
     return $this->belongsTo(\App\User::class, 'user_id', 'id'); 
 
    } 
 

 
    public function post_stacks() 
 
    { 
 
     return $this->hasMany(\App\PostStack::class); 
 
    } 
 

 
    public function post_os() 
 
    { 
 
     return $this->hasMany(\App\PostOS::class, 'post_id', 'id'); 
 
    } 
 

 
    public function post_tags() 
 
    { 
 
     return $this->hasMany(\App\PostTag::class , 'post_id', 'id'); 
 
    } 
 

 
    public function getCreatedAtAttribute($value) 
 
    { 
 
     return Carbon::parse($value)->toFormattedDateString(); 
 
    } 
 

 
}

PostController.php

class PostController extends Controller 
 
{ 
 
    public function index() 
 
    { 
 
     $posts = Post::all(); 
 

 
     foreach($posts as $post){ 
 
      $post->user; 
 
      $post->created_at; 
 
      $posts_os = $post->post_os; 
 
      $post_stacks = $post->post_stacks; 
 
      $post_tags = $post->post_tags; 
 

 
      foreach($posts_os as $post_os){ 
 
       $os = OS::where('id', $post_os->os_id)->first(); 
 
       $post_os['body'] = $os['body']; 
 
      } 
 

 
      foreach($post_stacks as $post_stack){ 
 
       $stack = Stack::where('id', $post_stack->stack_id)->first(); 
 
       $post_stack['url'] = $stack['url']; 
 
       $post_stack['body'] = $stack['body']; 
 
      } 
 

 
      foreach($post_tags as $post_tag){ 
 
       $tag = Tag::where('id', $post_tag->tag_id)->first(); 
 
       $post_tag['body'] = $tag['body']; 
 
      } 
 
     } 
 

 
     return response()->json($posts); 
 
    } 
 

 
}

我的JSON数据响应

[ 
 
    { 
 
     "id":1, 
 
     "title":"Laravel + XAMPP", 
 
     "user_id":1, 
 
     "description":"I'll take you through the entire process of setting up a development environment for Laravel using XAMPP.", 
 
     "created_at":"Jun 12, 2017", 
 
     "updated_at":"2017-06-12 08:55:02", 
 
     "user":{ 
 
     "id":1, 
 
     "name":"EpIEhg7ciO", 
 
     "email":"[email protected]", 
 
     "created_at":"2017-06-12 08:55:02", 
 
     "updated_at":"2017-06-12 08:55:02" 
 
     }, 
 
     "post_os":[ 
 
     { 
 
      "id":1, 
 
      "post_id":1, 
 
      "os_id":1, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"Windows" 
 
     } 
 
     ], 
 
     "post_stacks":[ 
 
     { 
 
      "id":1, 
 
      "post_id":1, 
 
      "stack_id":1, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "url":"laravel.svg", 
 
      "body":"Laravel" 
 
     }, 
 
     { 
 
      "id":2, 
 
      "post_id":1, 
 
      "stack_id":2, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "url":"xampp.svg", 
 
      "body":"XAMPP" 
 
     } 
 
     ], 
 
     "post_tags":[ 
 
     { 
 
      "id":1, 
 
      "post_id":1, 
 
      "tag_id":1, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"laravel" 
 
     }, 
 
     { 
 
      "id":2, 
 
      "post_id":1, 
 
      "tag_id":2, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"xampp" 
 
     } 
 
     ] 
 
    }, 
 
    { 
 
     "id":2, 
 
     "title":"Laravel + Vagrant", 
 
     "user_id":1, 
 
     "description":"I'll take you through the entire process of setting up a development environment for Laravel using Vagrant.", 
 
     "created_at":"Jun 12, 2017", 
 
     "updated_at":"2017-06-12 08:55:02", 
 
     "user":{ 
 
     "id":1, 
 
     "name":"EpIEhg7ciO", 
 
     "email":"[email protected]", 
 
     "created_at":"2017-06-12 08:55:02", 
 
     "updated_at":"2017-06-12 08:55:02" 
 
     }, 
 
     "post_os":[ 
 
     { 
 
      "id":2, 
 
      "post_id":2, 
 
      "os_id":1, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"Windows" 
 
     }, 
 
     { 
 
      "id":3, 
 
      "post_id":2, 
 
      "os_id":2, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"Mac OS X" 
 
     }, 
 
     { 
 
      "id":4, 
 
      "post_id":2, 
 
      "os_id":3, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"Linux" 
 
     } 
 
     ], 
 
     "post_stacks":[ 
 
     { 
 
      "id":3, 
 
      "post_id":2, 
 
      "stack_id":1, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "url":"laravel.svg", 
 
      "body":"Laravel" 
 
     }, 
 
     { 
 
      "id":4, 
 
      "post_id":2, 
 
      "stack_id":3, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "url":"vagrant.png", 
 
      "body":"Vagrant" 
 
     } 
 
     ], 
 
     "post_tags":[ 
 
     { 
 
      "id":3, 
 
      "post_id":2, 
 
      "tag_id":1, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"laravel" 
 
     }, 
 
     { 
 
      "id":4, 
 
      "post_id":2, 
 
      "tag_id":3, 
 
      "created_at":"2017-06-12 08:55:02", 
 
      "updated_at":"2017-06-12 08:55:02", 
 
      "body":"vagrant" 
 
     } 
 
     ] 
 
    } 
 
]

我的JSON数据是正是我想要的。我只是觉得我的PostController实现效率低下,并且运行了太多的查询。我运行的查询太多,并且有嵌套循环。有没有一种干净的方式可以使用Laravel的方法/关系之一建立关系?

谢谢!

回答

2

你可以在栈模型上声明关系吗?您只排除在数据透视表上添加关系。如果是这样的:

class Post extends Model 
{ 
    public function stacks() 
    { 
     return $this->hasMany(\App\Stack::class); 
    } 
} 

class Stack extends Model 
{ 
    public function posts() 
    { 
     return $this->belongsToMany(\App\Post::class); 
    } 
} 

通过叠后模型中定义的字段,这应该是所有你需要的雄辩,使关系的工作。此外,您可以访问pivot属性,让您:

$post->pivot->somePropertyOnStack 

编辑从文档

摘录给你如何雄辩确定关系的总体思路:

请记住,Eloquent将自动确定注释模型上正确的外键列。按照惯例,Eloquent将采用拥有模型的“蛇情况”名称并以_id作为后缀。因此,对于这个例子,Eloquent会假设Comment模型中的外键是post_id。

并与连接表的关系:

确定了恋爱关系的连接表的表名,机锋将加入按字母顺序排列的两个相关的型号名称。

的文档的本节将介绍每个关系类型和雄辩如何发生他们:

https://laravel.com/docs/5.4/eloquent-relationships#defining-relationships

+0

我不太明白,你是如何与这两种模式?有没有外键建立关系? – 75Kane

+0

通过表名和你定义的字段。当你将它们添加到模型类时,雄辩会假设一些关于表之间关系的约定。 – btl

+0

请记住,这只适用于您的中间表名称字段名称。他们完全遵循雄辩的期望,所以你不需要“指导”如何建立关系的雄辩。 – btl