Laravel Eloquent - Select all columns plus a subquery using Eloquent only - laravel-5

I need to select all columns from a table and an additional columns using subquery in laravel's eloquent. For example,
SELECT *, (SELECT COUNT(*) FROM transactions WHERE transactions.customer=customers.id) AS transactions FROM customers
Right now, I have come up with using a raw query using selectRaw like:
$customers = Customer::selectRaw('*, (SELECT COUNT(*) FROM transactions WHERE transactions.customer=customers.id) AS transactions')->get();
But I'd like to do it the eloquent way, without using raw queries.

as i see here you have 1-N relation between customer and transaction , if you have set up your models with eloquent relationships belongTo and hasMany , then you can use the With for eager load subqueries :
Eloquent eager load and eager load count relation
//customers + transactions for each one
$customers = Customer:with('transactions')->get();
// customers + transaction count for each one
$customers = Customer:withCount('transactions')->get();
Customer Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
/**
* Get the transactions for the customer.
*/
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}
Transaction Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Transaction extends Model
{
/**
* Get the customer of this transaction.
*/
public function customer()
{
return $this->belongsTo(Customer::class);
}
}

Related

How to set softdeletes condition as first clause in query with laravel models?

I have a simple question. Could anyone help me please?
In laravel models, we can use Sotfdeletes trait. So this trait add the whereNull('deleted_at') sentence. It is ok. However, we have a big table and our queries are very slow.
We have Company model which use SotfDeletes trait. It has some scope methods such as createdAtBigger, nameLike, oneOfBoard etc.
This is the company model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
/**
* #method static|Builder createdAtBigger(\DateTime $datetime)
* #method static|Builder nameLike(string $name)
* #method static|Builder oneOfBoard(array $boardIds)
*/
class Company extends Model
{
use SoftDeletes;
public function scopeCreatedAtBigger(Builder $builder, $datetime)
{
return $builder->where('created_at', '>', $datetime);
}
public function scopeNameLike(Builder $builder, $name)
{
return $builder->where('name', 'LIKE', '%'.$name.'%');
}
public function scopeOneOfBoard(Builder $builder, $boardIds)
{
return $builder->whereIn('board_id', $boardIds);
}
/**
* the other methods and scopes
* ...
* ...
* ...
*/
}
When we try to use that model with these scopes, it likes that for example:
$companies = Company::nameLike('XX Company')
->oneOfBoard([1,2,3,4])
->createdAtBigger('2022-02-14')
->get();
and its sql is like that:
SELECT *
FROM company
WHERE name like '%XX Company%'
and created_at > '2022-02-14'
and board_id in(1,2,3,4)
and deleted_at=null;
You can see, the deleted_at clause is the last condition.
This table has mostly deleted rows.
I want to move deleted_at condition at the first.
If my sql will like that, it it will take half time than now:
But I couldn't.
SELECT *
FROM company
WHERE deleted_at=null
and name like '%XX Company%'
and created_at > '2022-02-14'
and board_id in(1,2,3,4);
I don't want to use deletedAtNotNull scope because this model is very huge. It has lots of calls.
How can I do it? Is that any way?
PS: Thanks for #timlewis, I have an index on deleted_at column.

one to one relationship between two table in laravel by controllers

I have a table user table and want to join address table with user table primary key which is foreign key in address table.
Please let me know how I can perform one to one relationship between both of these table by controllers in Laravel and display them in view.
You can simply achieve this by adding an eloquent relationship in Model files.
User.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the phone associated with the user.
*/
public function address()
{
return $this->hasOne(Address::class);
}
}
Address.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Address extends Model
{
/**
* Get the user that owns the phone.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
Note: Both of the above models will assume by default user_id as a foreign key in the Address table.
To access this relationship in Controller,
$address = User::find($user_id)->address;
To access this relationship in View,
{{ $user->address->pincode }}
Since this is a Duplicate post, you can refer to this
Display in VIEW of One to One relation in Laravel Relationship

How to convert sql query to eloquent in laravel

how to convert sql to eoquent
$getAllRequirementRecord = Requirement::select()
->join('requirement_locations','requirements.id','=','requirement_locations.requirement_id')
->join('locations','requirement_locations.location_id','=','locations.id')
->where('isdelete',2)
->where('requirements.id',$id)->get();
help to solve this problems
Let's say we've an eloquent Model named Requirement and we've a database table named requirements associated with that model and we have another model named requirementLocation associated with a database table named requirement_locations.
and we have a database relation ship between both tables "requirements" & "requirement_locations" based on the requirement_id
Requirement Model:
class Requirement extends Model{
protected $table = 'requirements';
}
RequirementLocation Model:
class RequirementLocation extends Model{
protected $table = 'requirement_locations';
}
and Now we need to setup a relationship between these two models like the database tables .. so inside the Requirement we're gonna use has many relationship
use App\RequirementLocation;
class Requirement extends Model{
protected $table = 'requirements';
public function locations(){
return $this->hasMany(RequirementLocation::class);
}
}
and simply to fetch your data use
$id = 1;
$getAllRequirementRecord = Requirement->whereHas('locations' , function($query){
$query->where('isdelete',2);
})->where('id',$id)->with('locations')->get();
You can use eloquent with SQL raw query likewise:
$activeusers = User::selectRaw('users.name, count(*) submitted_games')
->join('games', 'games.user_id', '=', 'users.id')
->groupBy('users.name')
->orderBy('submitted_games', 'DESC')
->get();
To output to the screen the last queries ran you can use this :
dd(DB::getQueryLog());
I hope you have created Requirement, Location and RequirementLocation models
So first add this code in Requirement.php model file:
public function locations()
{
return $this->hasMany('RequirementLocation', 'requirement_locations');
}
Then access the requirements like this :
$requirement = Requirement::where('id', $requirement_id)->first();
Now you can access locations like this :
$requirement->locations;

How can i display a table with two foreign keys in laravel

I have 3 tables
Users
-------------
user_id (PK)
user_name
Items_distributed
-------------
user_id (FK)
item_id(FK)
Item List
-----------------
item_id(PK)
item_name
Now i need to print Items_distributed table by taking both the user_id and item_id and dispaly their item_name and user_name
i dont know how to display both things at a time
if i display either item_name or user_name its working
but when i try to print both it is not working .
Can any one solve my problem .
This is how i print the values
in controller i use like this
$itemdata=item::orderBy('user_id','desc')->paginate(10);
and in view
i use
#foreach($itemdata as $value)
<tr>
<td>{{$value->items->item_name}}</td>
<td>{{$value->users->user_name}}</td>
<td>{!!Html::link("editItem/",'Edit',array('class'=>'btn-sm btn-warning margin-left-btn'))!!}
{!!Html::link("deleteItem/".$value->item_id,'Delete',array('class'=>'btn-sm btn-warning margin-left-btn'))!!}</td>
</tr>
#endforeach
You should use Laravel Eloquent Relationship. When you create model file for DB Table, You just put relation with other model.
If Relation has set, than Laravel it self fetch data from Related table.
In your case, Three models are created.
1) User Model.
2) Item Model.
3) ItemDestributed Model.
UserModel.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Other code goes here
**/
public function itemDestribution()
{
return $this->hasMany('App\ItemDistribution','foreign_key');
}
}
ItemModel.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Items extends Model
{
/**
* Other code goes here
**/
public function itemDestribution()
{
return $this->hasMany('App\ItemDistribution','foreign_key');
}
}
ItemDestributionModel.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ItemDestribution extends Model
{
/**
* Other code goes here
**/
public function user()
{
return $this->belongsTo('App\User','foreign_key_of_user');
}
public function item()
{
return $this->belongsTo('App\Item','foreign_key_of_item');
}
}
You can find more about Eloquent Relation from Here.

getting pivot columns in collection in laravel

how to return collection of eloquent models with pivot column? For example, there are M:N relationship between users and vats. I want to retrieve all users data( with vats and with pivot column (costOfDelivery) , which is in pivot table user_vat).
In my code I have:
$vats = Vat::whereHas('users', function($query) use ($user) {
$query->where('user_id', $user->id);
})->with('country')
->get();
but this return data from vats and country, not from pivot table "user_vat", how to retrieve also costOfDelivery?
To retrieve the data from pivot table, you must use pivot attribute
Something like this
foreach($users->roles as $role){
echo $role->pivot->created_at;
}
To return json, you can use the toJson() method like
$vat->toJson();
<?php
/**
* The model class with the belongsToMany user class relation.
*/
class Vat extends Model
{
public function user()
{
return $this->belongsToMany(\App\User::class)
->withPivot(['cost_of_delivery', /**Specific columns for the pivot.*/]);
}
}
<?php
/*
* Your query (which I think is a little bit complicated that it should be.
*/
$vats = Vat::whereHas('users', function($query) use ($user) {
$query->where('user_id', $user->id);
})->with(['country', 'users'])
->get();
I would use sth. like:
<?php
$user->load(['vats.country']);
$vats = $user->getRelationValue('vats');
And
$vats->first()->pivot->cost_of_delivery
should give you the cost of delivery of the first vat.

Resources