Ajeesh
Ajeesh

Reputation: 5860

Laravel eloquent model how to get data from relationship's table

I am developing a laravel application which has the following eloquent models

I have a controller 'ProductController' where the following code is available

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

I am exposing RESTfull API which will allow my users to get all product details (including skus, shipping types etc..).

Suppose if I have an API GET : /products

The code which fetches all the product details will be some what the following

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.
}

Now my question is , is this logic proper? In this case all the logics are in the controller since im using eloquent models I have a model for each table and the relationships are defined in it. Is there a way I can get all the details of a product/associated model (Products details (in table 1)+ Sku details (in table 2)) rather than using the below

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

I am pretty new to laravel development and eloquent models. I will be using repository pattern for the development and in that case where does the aboe logic (Product+Sku combining) resides.

Please help out.

Upvotes: 25

Views: 156419

Answers (4)

Vishrut_Naik
Vishrut_Naik

Reputation: 11

You can try this:

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

}

This will give you the exact result in the object form.

Upvotes: 0

Kaushik shrimali
Kaushik shrimali

Reputation: 1228

If the repository pattern is used, do it like this.

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

Upvotes: 2

Moppo
Moppo

Reputation: 19275

Yes, you can get the details of the products and skus without making one additional query per product using eager loading ( this is referred as the typical N+1 query problem where N is the number of the products )

Suppose the relation between your Product and Sku models model is:

Product

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

To fetch the products data along with the sku data you can use the with method. In your controller:

Controller

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

Then, in your views, you can get the info this way:

View

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

For the repository question: if you want to use a repository you can place the eloquent-access part of your code inside the repository. So, for example you could have this method inside the repository:

ProductRepository

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

then you can use your repository in your controller:

Controller

//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();
}

Upvotes: 49

Fester
Fester

Reputation: 883

If I understand your question correctly, you can use eager loading.

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

This will give you an array of products that have a skus array in each product object.

Upvotes: 1

Related Questions