2017-06-17 49 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