Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

  • Product hasMany('App/Sku','products_id')
  • Sku belongTO('App/Product')

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.

like image 373
Ajeesh Avatar asked Dec 04 '15 06:12

Ajeesh


People also ask

What is with () in Laravel?

with() function is used to eager load in Laravel. Unless of using 2 or more separate queries to fetch data from the database , we can use it with() method after the first command. It provides a better user experience as we do not have to wait for a longer period of time in fetching data from the database.

Where condition fetch data from database in Laravel?

$categoryOne = DB::table('posts') ->where('category_id', 1); $categoryTwo = DB::table('posts') ->where('category_id', 2) ->union($categoryOne) ->get();


3 Answers

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();
}
like image 110
Moppo Avatar answered Oct 11 '22 10:10

Moppo


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.

like image 45
Fester Avatar answered Oct 11 '22 10:10

Fester


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

public function index() {
    $data = $this->passportRepository->with('user')->findWhere(['id'=>1]);
}
like image 2
Kaushik shrimali Avatar answered Oct 11 '22 11:10

Kaushik shrimali