Reputation: 5860
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
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
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
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
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