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.
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.
$categoryOne = DB::table('posts') ->where('category_id', 1); $categoryTwo = DB::table('posts') ->where('category_id', 2) ->union($categoryOne) ->get();
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();
}
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.
If the repository pattern is used, do it like this.
public function index() {
$data = $this->passportRepository->with('user')->findWhere(['id'=>1]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With