Multiple orWhere() in whereHas() in Laravel 5 - laravel

Contact Model
class Contact extends Model
{
public function Account()
{
return $this->belongsTo('app\Account');
}
}
Account Model
class Account extends Model
{
public function Contact()
{
return $this->hasMany('app\Contact');
}
}
I want to get query of all Contacts that have account_name = 'test' or account_city ='test2'.
$query = Contact::query();
$query->whereHas('Account', function ($q) {
$q->orwhere('account_name' ,'=', 'test');
$q->orwhere('account_city','=','test2');
});
$query->get;
This query shows me all Contacts that have an Account but I want to get only Contacts that have account_name = 'test' or account_city ='test2'
Result of $query->tosql();
select * from `contacts` where exists (select * from `accounts` where (`contacts`.`account_id` = `accounts`.`id` or (`account_name` = ? or `account_city` = ?)) and `accounts`.`deleted_at` is null) and `contacts`.`deleted_at` is null

try this:
$query=Contact::query();
$query->whereHas('Account', function ($q) {
$q->where(function($query) {
$query->where('account_city','test2')->orWhere('account_name','test');
});
});
$query->get();

$query=Contact::query();
$query = $query->whereHas('Account', function ($q) {
$q->orwhere('account_name',test');
$q->orwhere('account_city','test2');
});
$query->get;
I think it will do the trick.

Related

how to implement 3 nested subquery with 3 model in laravel?

I have 3 model Transaction , Cart , Acceptedcart.
in Cart model I have transaction_id and in Acceptedcart model have cart_id.
how can I find transactions where acceptedcart->delivered == true ?
can I write that like this ?
$transactions = Transaction::whereIn('id',function ($query) {
return Cart::whereIn('id' , function($subquery){
return AcceptedCart::where('delivered' , false)->pluck('cart_id');
})->pluck('transaction_id');
})->get();
or :
$transactions = Transaction::whereIn('id' , function($query){
$query->select('transaction_id')->from('carts')->whereIn('id' , function($subquery){
$subquery->select('cart_id')->from('accepted_carts')->where('delivered' , true);
});
})->get();
thanks.
in Transaction.php your relationship to carts:
public function carts()
{
return $this->hasMany(Cart::class);
}
in Cart.php you relationship to accepted carts:
public function accepted_carts()
{
return $this->hasMany(Acceptedcart::class);
}
And the query to get the transactions where acceptedcart->delivered == true:
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('delivered', true);
})->get();

I'm getting a query error when adding paginate to my livewire component

My component lists user teams within a radius of an (friendly) event. I added the ability to search by team name. This all works fine until I try to add paginate.
This is the error I get after adding ->paginate($this->perPage)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.id' in 'where clause'
(SQL: select count(*) as aggregate from `teams` where `users`.`id` = `teams`.`user_id`
and `division` = 12U and `name` like %%)
Her is my Livewire component:
class ListAreaTeams extends Component
{
use WithPagination;
public $friendly;
public $searchTeam = '';
public $perPage = 5;
public function render()
{
// Get friendly
$friendly = $this->friendly;
$users = User::query()->whereHas('teams', function($q) use ($friendly){
$q->where('division', $friendly->division)
->searchTeam($this->searchTeam)
->paginate($this->perPage);
})
->where('id', '!=', $friendly->user_id)
->distance($friendly->latitude, $friendly->longitude);
return view('livewire.list-area-teams', [
'users'=> $users
]);
}
}
#lagbox thanks for the hint. I was able to fix this by using a foreach on the users->teams. Not very pretty but it does the job.
class ListAreaTeams extends Component
{
use WithPagination;
public $friendly;
public $searchTeam = '';
public $perPage = 10;
public function render()
{
$friendly = $this->friendly;
$users = User::with('teams')
->where('onboard_completed', 1)
->where('id', '!=', $friendly->user_id)
->distance($friendly->latitude, $friendly->longitude);
$teams = [];
foreach($users as $user) {
foreach($user->teams as $team) {
$teams[] = $team;
}
}
$teams = $team
->where('division', $friendly->division)
->searchTeam($this->searchTeam)
->paginate($this->perPage);
return view('livewire.list-area-teams', [
'teams'=> $teams
]);
}
}

Laravel Using nested with

I couldn't do what I wanted to do with Laravel, actually what I want to do is as follows,
I send getTruck id and list truckHistory with witdh, and I want to pull trukInvoice information with truckHistory invoice_id. But i am getting error where am i doing wrong?
Mysql Connection is as follows.
http://localhost:3000/truck/1
"trucks" table column "plate"
"invoice_details" column "plate_no"
"invoice_details" column "invoice_id"
"invoice" column "id"
Truck Controller
public function getTruck($id)
{
$truck = Truck::find($id)->with([
'truckHistory' => function($query){
// return $query->with(['trukInvoice']);
}
])->first();
return $truck;
}
Truck Model
public function companys()
{
return $this->belongsTo(Contact::class, 'company_id', 'id');
}
public function getCompanyNameAttribute()
{
return $this->companys()->first()->name;
}
public function truckHistory(){
return $this->hasMany(InvoiceDetail::class,'plate_no','plate');
}
public function trukInvoice(){
return $this->belongsTo(Invoice::class,'invoice_id','id');
}
Try this:
$truck = Truck::leftJoin('invoices', 'trucks.invoice_id', 'invoices.id')
->leftJoin('invoice_details', 'trucks.plate_no', 'invoice_details.plate')
->select('*')
->first();
or
$truck = Truck::with(['invoices' => function ($query) {
$query->whereHas('invoice_details', function ($q){
$q->whereNotNull('invoice_details.plate');
});
}])->first();
Check the documentation on restraining eager loads.

Laravel whereHas Filter sub relation

Is that any method to filter the employees and the manpower table record does not return also?
$result = Pwra::with('purchaseOrder', 'manpower')
->where('pwra_dt', $date)
->where('time_session', $session)
->whereHas('manpower.employees', function ($q) {
$q->where('status', 1);
})
->get();
Pwra Class
public function manpower()
{
return $this->hasMany('App\Models\Manpower', 'pwra_uuid', 'pwra_uuid');
}
Manpower Class
public function employee()
{
return $this->hasOne('App\Models\Employees', 'employees_uuid', 'employees_uuid')->where('status', 1);
}
What I expected is: When the employees Status = 0, it will not return any record even manpower.
you can try 2 level whereHas()
$result = Pwra::with('purchaseOrder', 'manpower')
->where('pwra_dt', $date)
->where('time_session', $session)
->whereHas('manpower', function ($q) {
$q->whereHas('employees',function($subQ){
$subQ->where('status', 1);
});
})
->get();
whereHas('manpower.employees' it will not work

How to do join table by ID as primary key in query -laravel

I want to do a function where filter based on 2 database tables. However, Im not sure how to put the join table in the query. Which means the data will be filtered from two table (user and employee tables) before returning the result to the datatable.
My filter query is
public function filterQuery(Request $request){
$age = $request->age;
$gender= $request->gender;
$query = user::query();
if(!empty($request->age)){
$query->where('age','>=',$age );
}
if(!empty($request->gender)){
$query->where('gender','<=',$gender);
}
$data = $query->get();
return datatables()->of($data)->make(true);
}
The table that I want to join in the query is from table employee (column = income and house_ownership) .and the primary key that connect both tables is IC.
If you have relationship in both model, you can use whereHas:
if(!empty($request->income) || !empty($request->house_ownership)){
$query->whereHas('employee', function($q) use ($income, house_ownership) {
if (!empty($income)) {
$q->where('income', $income);
}
if (!empty($house_ownership)) {
$q->where('house_ownership', $house_ownership);
}
});
}
...
Or you can just use join or leftjoin to filter another table:
public function filterQuery(Request $request){
$age = $request->age;
$gender= $request->gender;
$house_ownership = $request->house_ownership;
$income= $request->income;
$query = user::query();
$query->leftjoin('employee', 'employee.IC', '=', 'user.IC');
if(!empty($request->age)){
$query->where('user.age','>=',$age );
}
if(!empty($request->gender)){
$query->where('user.gender','<=',$gender);
}
if(!empty($request->income)){
$query->where('employee.income', $income);
}
if(!empty($request->house_ownership)){
$query->where('employee.house_ownership', $house_ownership);
}
$data = $query->select('user.*')->get();
return datatables()->of($data)->make(true);
}
Try This
public function filterQuery(Request $request){
$age = $request->age;
$gender= $request->gender;
if(!empty($request->age)){
$data = User::where('age','>=',$age)->get();
}
if(!empty($request->gender)){
$data = User::where('gender','<=',$gender)->get();
}
return datatables()->of($data)->make(true);
}
You can use Eloquent::when() to reduce if-else for Conditional Queries.
public function filterQuery(Request $request){
$query = user::query();
$query->select('user.*')->join('employee', 'employee.IC', '=', 'user.IC');
$data = $query
->when(request('age') != null , function ($q) {
return $query->where('user.age','>=',request('age'));
})
->when(request('gender') != null , function ($q) {
return $query->where('user.gender','<=',request('gender'));
})
->when(request('income') != null , function ($q) {
return $query->where('employee.income','<=',request('income'));
})
->when(request('house_ownership') != null , function ($q) {
return $query->where('employee.house_ownership','<=',request('house_ownership'));
})
->get();
return datatables()->of($data)->make(true);
}

Resources