How to convert Database Query Builder to Database Eloquent? - laravel

How to convert Database Query Builder to Database Eloquent?
$products = DB::table('carts')
->join('products','.carts.product_id','=','products.id')
->where('carts.user_id',$userID) ->select('products.*')
->get();

As you've provided very little information to assist you with, some assumptions are going to be made such as naming conventions and relationship types.
Product.php
Add a carts relationship to your Product model. This assumes a Product can belong to many Carts.
public function carts()
{
return $this->belongsToMany(Cart::class);
}
Cart.php
Add a products relationship to your Cart model. This assumes a Cart can have many Products.
public function products()
{
return $this->belongsToMany(Product::class);
}
Create a pivot table which will maintain the relationships between Carts and Products:
php artisan make:migration create_cart_product_table
Then add your relationship foreign keys to the migration:
public function up()
{
Schema::create('cart_product', function (Blueprint $table) {
$table->id();
$table->foreignId('cart_id')->constrained();
$table->foreignId('product_id')->constrained();
$table->timestamps();
});
}
To add Products to a Cart, you can use the attach or sync methods, for example:
$products = Product::inRandomOrder()->take(5)->pluck('id');
Cart::create(['user_id' => 1])->products()->attach($products);
The above will get 5 Products (at random) from your products table, then create a new Cart with the given user id and attach those Products to the Cart.
To retrieve a Cart and it's associated Products, you would do the following:
$cart = Cart::where('id', $id)->with('products');
The $cart variable can be passed to a view or in a json response where after you can iterate over the Products in the Cart.
$cart = Cart::where('id', $id)->with('products');
return view('cart', compact('cart'));
blade view
<ul>
#foreach ($cart->products as $product)
<li>{{ $product->name }}</li>
#endforeach
</ul>
If you want to get all the Cart records for a given User, you would do the following:
$carts = Cart::where('user_id', $id)->with('products')->get();
return view('carts', compact('carts'));
blade view
#foreach ($carts as $cart)
{{ $cart->id }}
<ul>
#foreach ($cart->products as $product)
<li>{{ $product->name }}</li>
#endforeach
</ul>
<hr />
#endforeach
Or something to that effect.

Related

How to get information from 3 separate tables in Laravel

I have a table called users that stores user information and each user can have multiple business accounts that are stored in separate tables.
Models:
User:
id
name
UserProviderAccount:
id
user_id
bussiness_name
bussiness_tell
bussiness_address
UserCompanyAccount
id
user_id
company_name
company_size
UserInfluencerAccount:
id
user_id
name
website
follower_count
Tables Relations :
User :
public function providers(): HasMany
{
return $this->hasMany(UserProviderAccount::class);
}
public function companies(): HasMany
{
return $this->hasMany(UserCompanyAccount::class);
}
public function influencers(): HasMany
{
return $this->hasMany(UserInfluencerAccount::class);
}
I want to display the user's business accounts of all three types at once.
How do I do this?
You simply need to load and call the relationships as follows:
UserController: sample controller and function
public function show(User $user){
//Here we will load all of the relationships for the specific user
$user->load('providers', 'companies', 'influencers');
//Assign the providers from user->providers
$providers = $user->providers;
//Assign the companies from user->companies
$companies = $user->companies;
//Assign the influencers from user->influencers
$influencers = $user->influencers;
//Send all of the data to the view
return view('users.show', compact('user', 'providers', 'companies', 'influencers'));
}
users.show View: simplified version to show you concept.
<p>{{$user->name}}</p>
<p>The providers:</p>
<ul>
#foreach($providers as $provider)
<li>{{$provider->bussiness_name}}</li>
<li>{{$provider->bussiness_tell}}</li>
<li>{{$provider->bussiness_address}}</li>
#endforeach
</ul>
<p>The companies:</p>
<ul>
#foreach($companies as $company)
<li>{{$company->company_name}}</li>
<li>{{$company->company_size}}</li>
#endforeach
</ul>
<p>The influencers:</p>
<ul>
#foreach($influencers as $influencer)
<li>{{$influencer->name}}</li>
<li>{{$influencer->website}}</li>
<li>{{$influencer->follower_count}}</li>
#endforeach
</ul>

Show many products from a category from many-to-many relationship in laravel

So I’m making a catalogue using Laravel 7.* and I have a problem.
I have many products and many categories. I have created a many-to-many relationship so a product can be in many categories.
Now, what I am trying to do is to show in a page each category with related products, but obviously I am doing something wrong.
Below you may see some code:
Product.php:
public function categories()
{
return $this->belongsToMany(Category::class);
}
Category.php:
public function product()
{
return $this->belongsToMany(Product::class);
}
Show.blade.php
#php
$products = \App\Product::with('categories')->find(1);
#endphp
#foreach ($products as $id)
{{ $id->name }}<br>
#endforeach
Any help please?
Fixed it.
I fetched categories in controller and send to view. Then for each category displayed each product.
Get all the categories and show products related to them.
#php
$categories= \App\Category::all();
#endphp
#foreach($categories as $category)
#foreach($category->product as $product)
{{$product->name}}
#endforeach
#endforeach
You need also Id of category that you want to show products related to it.
According To This answer
Try this:
$category_id = 1; // Desired Category Id
$products = \App\Product::whereHas('categories', function($query) use ($category_id) {
$query->where('category_id', $category_id);
})->paginate();
I also added pagination.

Laravel - Populating view with info from single row (with pivot data)

I currently have a form/view that allows a User to save an Order. This also updates a pivot table with the respective Products and qtys. What I am trying to do, is after this information is inputted and saved into the database, I want to send the user to a checkout page that shows all the information they inputted for that Order.
Relationships
User hasMany Order
Order belongsToMany Product
Product belongsToMany Order
checkout.blade.php
#foreach ($orders as $order)
#foreach ($order->products as $product)
<tr>
<td>{{ $product->name }}</td>
<td>{{ $product->pivot->qty }}</td>
</tr>
#endforeach
#endforeach
OrderController.php
public function checkout($id)
{
$user = Auth::user();
$user->load("orders.products"); //eager load pivot table
$orders = $user->orders->where('order_id', $id);
return view('orders.checkout', compact('orders', 'user'));
}
I know I am calling the order incorrectly, because if I change
$orders = $user->orders->where('order_id', $id);
to
$orders = $user->orders;
It displays correctly, except of course, it populates with every Order's detail.
Or is there some elegant way for me to pass the data from the checkout function without this additional query? (I understand about moving data in Sessions, but I am working with a pivot table, and that complicates things.
If on the checkout page, you want to use just the latest order that the user has made, then you can just load that order using route model binding
Route::get('checkout/{order}', 'OrdersController#checkout');
Then in your controller:
public function checkout(Order $order)
so from here, you can pass this order to the view, and list all the products from this order, and also in your Order model you should have a reference to the user that this order belongs to:
public function user()
{
return $this->belongsTo(User::class);
}
Accessing columns from the pivot table will be:
#foreach($order->products as $product)
<div> {{ $product->pivot->column }} </div>
#endforeach

How to count how many articles belongs which category?

I have this relationships:
ARTICLES
public function category()
{
return $this->belongsTo('App\Models\Categories');
}
CATEGORY have translations
public function c_translations()
{
return $this->hasMany('App\Models\CategoryTranslations', 'category_id');
}
In articles i have category id, also in translations i have category_id. So how can i count how many articles have each category. Any suggestion?
$articles = Articles::all();
foreach($articles as $article ){
$articles_category = Articles::where('id',$article->id)->withCount('category')->first();
}
I tried this but always get 0 for all of categories
Define a hasMany relation in your Category model as:
public function articles()
{
return $this->hasMany('App\Models\Article');
}
Then you can use withCount to query it as:
$categories = Category::withCount('articles')->get();
Pass it to your view and then you can access the no. of articles of category as:
#foreach ($categories as $category)
<li>{{ category->title }}</li>
<li>{{ category->articles_count }}</li>
#endforeach
Use withCount() method to count relation.
Model::where('id', $id)->withCount('relation')->first();
If you want to count the number of results from a relationship without actually loading them you may use the withCount method, which will place a {relation}_count column on your resulting models.
I think you should use a group by statement.
You select category_id,COUNT(*) FROM articles GROUP BY category_id
This will return the number of articles for each category_id

How to safely access other users and other model's records inside Blade template

I have 3 models in my app Users, Sales and Plans, when I render sales for each customer (due to storing) I only get id's for other users and models related to that sale (like account manager, owner, plan), now I'm trying to use those ID's inside blade to get names or other rows based on ID and model. Here is the show function:
public function show($id) {
$user = User::find($id);
$sales = Sale::where('customer_id', '=', $id)->get();
return view('profiles.customer', ['user' => $user, 'sales' => $sales]);
}
And in blade I get all those sales like:
#foreach ($sales as $sale)
<li>
<i class="fa fa-home bg-blue"></i>
<div class="timeline-item">
<span class="time"><i class="fa fa-clock-o"></i> {{$sale->created_at->format('g:ia, M jS Y')}}</span>
<h3 class="timeline-header">{{$user->name}} became a customer</h3>
<div class="timeline-body">
<p>Date: {{$sale->sold_date}}</p>
<p>Price: {{$sale->sale_price}}</p>
</div>
</div>
</li>
#endforeach
So inside each record I have like "account_manager_id", "agent_id", "owner_id", "plan_id".
Currently I have this solved by adding public static function (this is for users, have same function for Plan model as well) in Sale model class:
public static function getUser($id) {
return User::where('id', $id)->first();
}
And I'm using it like this in Blade:
Account manager: {{$sale->getUser($sale->account_mgr_id)->name}}
Is this the safest and best way to do it? Or there is something I'm overlooking here?
You need to add relationships in your Sales Model.
class Sales extends Eloquent {
.....
.....
public function accountManager() {
return $this->hasMany('App\User', 'account_manager_id');
}
public function agents() {
return $this->hasMany('App\User', 'agent_id');
}
public function owner() {
return $this->hasOne('App\User', 'owner_id');
}
}
Now $sales->agents will give you a user with agent_id as id in User table.
Update your hasOne, hasMany relationships as your need. Laravel Documentation.
From your blade template, your access your AccountManager as
#foreach($sales->accountManager as $manager)
Name: {{ $manager->name}}
#endforeach
I think you could use Eloquent relationships. Taking your example, you should define relationship in your User model:
<?php
class User extends Eloquent {
public function sales() {
return $this->hasMany(Sale::class, 'customer_id');
}
}
Then, whenever you need to get sales of that user (entries, that relate via customer_id column), just simply do
<?php
$user = User::find($id);
$sales = $user->sales;
This is very fun when when you have to print out list of users that have sales, for example
<?php
public function showUsersWithSales() {
$users = User::with('sales')->get();
return view('users-with-sales', compact('users'));
}
users-with-sales.blade.php example:
#foreach ($users as $user)
User: {{ $user->name }}<br>
Sales:<br>
#foreach ($user->sales as $sale)
{{ $sale->amount }} {{ $sale->currency }} # {{ $sale->created_at }}<br>
#endforeach
<hr>
#endforeach
It would print all users with their sale amount and currency, followed by date when it was created.
This sample takes into account, that your User model has name attribute and your Sale model has amount, currency, created_at and customer_id fields in your database.
To reverse the action, say you have a sale and want to know who made it, just simply define a relationship!
<?php
class Sale extends Eloquent {
public function customer() {
return $this->belongsTo(User::class, 'customer_id');
}
}
Hope that helps!
Eloquent Relationship is your friend, https://laravel.com/docs/5.2/eloquent-relationships and you can solve your problem easily.
Suggestion is to remove all those function access and control from view and put it somewhere else. This will be good habit for you so you can avoid the infamous fat view.

Resources