2014-02-16 63 views
11

我正在嘗試學習存儲庫模式,似乎讓我自己有點混淆,因爲我急於加載關係時如何使用這個存儲庫模式,並將數據庫邏輯保留在我的控制器之外。Laravel - 使用存儲庫模式

我的存儲庫/應用程序結構的快速概覽。

app/ 
    Acme/ 
    Repositories/ 
     RepositoryServiceProvider.php 
     Product/ 
     EloquentProduct.php 
     ProductInterface.php 
     Category/ 
     EloquentCategory.php 
     CategoryInterface.php 

例ProductInterface.php

<?php namespace GD\Repositories\Product; 

interface ProductInterface 
{ 
    public function all(); 

    public function find($id); 

    public function findBySlug($slug); 
} 

例CategoryInterface.php

<?php namespace GD\Repositories\Category; 

interface CategoryInterface 
{ 
    public function all(); 

    public function find($id); 

    public function findBySlug($slug); 
} 

好了,所以比較容易的部分是利用DI噴射模型的依賴關係到控制器中。

列出所有類別相關產品更困難,因爲我不再使用雄辯模型。我正在使用一個沒有公開所有雄辯方法的界面。

這不會沒有我實現我的EloquentCategory類中方法工作...

public function show($slug) 
{ 
    return Response::json($this->category->findBySlug($slug)->with('products'), 200); 
} 

我應該創建一個單獨的服務類兩個儲存粘合在一起?例如允許以下內容

public function __construct(ShopService $shop) 
{ 
    $this->shop = $shop; 
} 

public function show($slug) 
{ 
    return Response::json($this->shop->getProductsInCategory($slug), 200); 
} 

或者,我是否應該在我的Category Repository中實現with方法?

public function with($relation) 
{ 
    return Category::with($relation); 
} 

最後,我是否理解了Repository Pattern的用法正確?

+5

app/Acme/etc ...有人來自laracasts:P –

回答

17

你是在思考,倉庫只是之間的鏈接/橋樑您controllermodel,因此控制器直接在庫中,您可以聲明使用model從那裏你的方法,例如使用repository類,而不是model

<?php namespace GD\Repositories\Category; 

interface CategoryInterFace{ 

    public function all(); 

    public function getCategoriesWith($with); 

    public function find($id); 
} 

現在實施庫類接口:

<?php namespace GD\Repositories\Category; 

use \EloquentCategory as Cat; // the model 
class CategoryRepository implements CategoryInterFace { 
    public function all() 
    { 
     return Cat::all(); 
    } 

    public function getCategoriesWith($with) 
    { 
     return Cat::with($with)->get(); 
    } 

    public function find($id) 
    { 
     return Cat::find($id): 
    } 
} 

要在你的控制器使用方法:

<?php 

use GD\Repositories\Category\CategoryInterFace; 

class CategoryController extends BaseController { 

    public function __construct(CategoryInterFace $category) 
    { 
     $this->cat = $category; 
    } 

    public function getCatWith() 
    { 
     $catsProd = $this->cat->getCategoriesWith('products'); 
     return $catsProd; 
    } 

    // use any method from your category 
    public function getAll() 
    { 
     $categories = $this->cat->all(); 

     return View::make('category.index', compact('categories')); 
    } 

} 

注:倉庫的省略IoC結合,因爲這不是你的問題,你知道的。

更新:我在這裏寫了一篇文章:LARAVEL – USING REPOSITORY PATTERN

+1

+1 ....我有一個小問題。假設我通過控制器構造函數通過'$ this-> model = somemodel()'來分配一個模型實例。如果我使用存儲庫模式,我將創建接口,模型和服務提供者來注入。我可以輕鬆更改界面。 __but__我也可以在構造函數中更改模型(如上所述)並使用它....使用接口的實際好處是什麼? (如果它太寬泛,我會寫一個問題,並希望你會回答):) – itachi

+0

我想你已經錯過了這個問題......或者我真的在想什麼。我知道如何從我的存儲庫中獲得'all'。我已經在我的例子中完成了。我想知道的是如何在使用接口時使用IOC來「加載」。在你的答案中,它是如何給我這樣做的......'$ categories = $ this-> cat-> with('products') - > get();'因爲'with'不存在於'CategoryInterface'我應該實現嗎?或者我應該創建一個同時使用兩者的'glue'倉庫? – Gravy

+0

@itachi - 開始一個新的問題,我會爲你回答。 – Gravy

1

有一個非常簡單的方法來做到這一點,它是深入探討在這個環節

http://heera.it/laravel-repository-pattern#.U6XhR1cn-f4

我一直在尋找確切的解決方案,它運作良好,到目前爲止

所以您的想法將是在您的存儲庫代碼中聲明這個

public function __construct(\Category $category) 
{ 
    $this->category = $category; 
} 
public function getAllUsers() 
{ 
    return $this->category->all(); 
} 

public function __call($method, $args) 
{ 
    return call_user_func_array([$this->category, $method], $args); 
} 

強制模型被調用時,一些功能是失蹤

+0

謝謝你的回答。在這個網站,我們很欣賞引用他們的來源的答案。但是鏈接本身可以在以後被破解,所以你可以在內容中添加至少一些元素。 –