web-dev-qa-db-ja.com

Laravel雄弁なモデルリレーションシップのテーブルからデータを取得する方法

私はlaravel以下の雄弁なモデルを持つアプリケーションを開発しています

  • 製品hasMany( 'App/Sku'、 'products_id')
  • Sku belongsTO( 'App/Product')

次のコードが利用可能なコントローラー「ProductController」があります

public function index()
{    
    $products = Product::all();
    foreach($products as $product){
            $products_id = $product->products_id;
    }
}

ユーザーがすべての製品の詳細(skus、配送タイプなどを含む)を取得できるようにするRESTfull APIを公開しています。

APIがある場合GET:/ products

すべての製品の詳細を取得するコードは次のようになります

public function index()
{              
      $products = Product::all();
      foreach($products as $product){
          $products_id = $product->products_id;
          $skus_data = Product::find($products_id)->skus;
      }
        // Now I have both the product details + skus which I can bundle into an array/json.
}

さて、私の質問は、このロジックは適切ですか?この場合、すべてのロジックはコントローラー内にあります。なぜなら、雄弁なモデルを使用すると、各テーブルのモデルがあり、関係が定義されているからです。以下を使用するのではなく、製品/関連モデルのすべての詳細(製品の詳細(表1)+ Skuの詳細(表2))を取得する方法はありますか

foreach($products as $product){
    $products_id = $product->products_id;
    $skus_data = Product::find($products_id)->skus;
}

laravel開発と雄弁なモデル。開発にリポジトリパターンを使用し、その場合はaboeロジック(Product + Skuの組み合わせ)が存在します。

手伝ってください。

11
Ajeesh

はい、 eager loading (これは典型的なN + 1クエリ問題と呼ばれますここで、Nは製品の数です)

ProductモデルとSkuモデルモデルの関係が次のとおりであるとします。

製品

public function skus()
{
    return hasMany('App/Sku','products_id');
}

Skuデータとともに製品データを取得するには、withメソッドを使用できます。コントローラーで:

コントローラー

 $products = Product::with('skus')->get();

次に、ビューでこの方法で情報を取得できます。

表示

foreach ($products as $product) 
{
     //$product->skus is a collection of Sku models
     dd( $product->skus );
}

リポジトリに関する質問:リポジトリを使用する場合は、コードの雄弁なアクセス部分をリポジトリ内に配置できます。したがって、たとえば、リポジトリ内にこのメソッドを含めることができます。

ProductRepository

public function getProductsData() 
{
    //access eloquent from the repository
    return Product::with('skus')->get();    
} 

次に、コントローラーでリポジトリを使用できます。

コントローラー

//inject the repository in the controller
public function __construct( ProductRepository $productRepo )
{
    $this->productRepo = $productRepo;
}

//use the injected repository to get the data
public function index()
{
    $products = this->productRepo->getProductsData();
}
25
Moppo

リポジトリパターンを使用する場合は、次のようにします。

public function index() {
    $data = $this->passportRepository->with('user')->findWhere(['id'=>1]);
}
1

私があなたの質問を正しく理解していれば、Eager Loadingを使用できます。

 public function index()
 {
    $products = Product::with('skus')->get();
 }

これにより、各製品オブジェクトにskus配列を持つ製品の配列が得られます。

1
Fester