Laravel troubles with WHERE in relationships - php

I'm having trouble when a user is not an admin. The goal is to get only those requests that belong to the user, but when I use the where clause, I get all the requests from the DB.
It was supposed to get all the requests only for an admin.
Thank you for the help!
public function index(){
$status = request('status', -1);
$paper_size = request('paper_size', -1);
if (auth()->user()->isAdmin()) {
$requests = Request::
where('paper_size', $paper_size)->orWhereRaw($paper_size. ' = -1')->
where('status', $status)->orWhereRaw($status. ' = -1')->
orderBy(
request('orderby') ? request('orderby') : 'created_at',
request('order') ? request('order') : 'DESC'
)->paginate(10);
$departments = Departament::All();
return view('Requests.index', compact('requests', 'departments'));
}
$requests = auth()->user()->requests()->
where('status', $status)->orWhereRaw($status. ' = -1')->
where('paper_size', $paper_size)->orWhereRaw($paper_size. ' = -1')->
orderBy(
request('orderby') ? request('orderby') : 'created_at',
request('order') ? request('order') : 'DESC'
)->paginate(10);
return view('Requests.index', compact('requests'));
}
UPDATE:
I can already list all user requests, but the status filter does not work.
Ps: the filter "paper_size" is working as expected
SOLVED:
Thanks to the whole community, and especially to #Sandeesh
public function index(){
request('status') == -1 || request('status') == null ?
$statusExists = false : $statusExists = true;
$status = request('status');
request('paper_size') == -1 || request('paper_size') == null ?
$paper_sizeExists = false : $paper_sizeExists = true;
$paper_size = request('paper_size');
$is_admin = auth()->user()->isAdmin();
$requests = Request::when($statusExists, function ($query) use ($status) {
return $query->where('status', $status);
})
->when($paper_sizeExists, function ($query) use ($paper_size) {
return $query->where('paper_size', $paper_size);
})
->when(!$is_admin, function ($query) {
return $query->where('owner_id', auth()->id());
})
->orderBy(request('orderby', 'created_at'), request('order', 'desc'))
->paginate(10);
if (!$is_admin) {
return view('Requests.index', compact('requests'));
}
$departments = Departament::all();
return view('Requests.index', compact('requests', 'departments'));
}

Wrap your where and orWhereRaw conditions together for a single column. Or use when instead of the workaround you apply with -1 = -1. I've also refactored the code for you.
public function index()
{
$status = request('status');
$paper_size = request('paper_size');
$is_admin = auth()->user()->isAdmin();
$requests = Request::when(!is_null($status), function ($query) use ($status) {
return $query->where('status', $status);
})
->when(!is_null($paper_size), function ($query) use ($paper_size) {
return $query->where('paper_size', $paper_size);
})
->when(!$is_admin, function ($query) {
return $query->where('owner_id', auth()->id());
})
->orderBy(request('orderby', 'created_at'), request('order', 'desc'))
->paginate(10);
if (!$is_admin) {
return view('Requests.index', compact('requests'));
}
$departments = Departament::all();
return view('Requests.index', compact('requests', 'departments'));
}

You would need to get the $user_id = Auth::id and then update the second query to have a where user_id = $user_id statement (I'm not sure which of those tables belongs to the user).

Try with:
$requests = Request::with('User')
->where('user_id',\Auth::user()->user_id)
->where('status', $status)
->orWhereRaw($status. ' = -1')
->where('paper_size', $paper_size)
->orWhereRaw($paper_size. ' = -1')
->orderBy(request('orderby') ? request('orderby') : 'created_at',
request('order') ? request('order') : 'DESC')->paginate(10);

Related

Too few arguments to function Illuminate\Http\Request::has(), 0 passed

I have seen many similar questions but most of the answers look complicated and do not seem too similar to my issues. Again, I am new to Laravel and would need the simplest form of explanation.
I want to don't show info in view, show up as long as I searched.
My Controller
public function index(Request $request)
{
$transactions = UserTransaction::query();
$userId = request()->get('userId');
$price = request()->get('price');
$type = request()->get('type');
$status = request()->get('status');
$ordering = request()->get('ordering');
if($userId){
$transactions->where('userId' , $userId);
}
if ($price) {
$transactions->where('price' , $price);
}
if ($type) {
$transactions->where('type' , $type);
}
if ($status) {
$transactions->where('status' , $status);
}
return view('admin.transaction.index',[
'transactions' => $transactions->paginate(5)->appends($request->except('page')),
'stats' => $stats
]);
}
My Blade
#if( $transactions->count() > 0 && request()->has() )
#foreach($transactions as $transaction)
{{ $transaction->id }}
{{ optional($transaction->user)->full_name }}
{{ $transaction->type }}
#endforeach
#endif
I get this error
I think you are looking for hiding view until user searched any one field.So you can do the following
#if( $transactions->count() > 0 &&collect($request->all())->filter()->isNotEmpty())
if you want to ignore page from checking then you can use except
collect($request->except('page'))->filter()->isNotEmpty()
Better don't execute query until one of the filter value is filled because any way you don't to display it in view
public function index(Request $request)
{
$userId = request()->get('userId');
$price = request()->get('price');
$type = request()->get('type');
$status = request()->get('status');
$ordering = request()->get('ordering');
$transactions=[];
if(collect($request->all())->filter()->isNotEmpty()){
$transactions = UserTransaction::query();
if($userId){
$transactions->where('userId' , $userId);
}
if ($price) {
$transactions->where('price' , $price);
}
if ($type) {
$transactions->where('type' , $type);
}
if ($status) {
$transactions->where('status' , $status);
}
$transactions->paginate(5)->appends($request->except('page'))
}
return view('admin.transaction.index',[
'transactions' =>$transactions,
'stats' => $stats
]);
}
Also instead of repeating collect($request->except('page'))->filter()->isNotEmpty() this in multiple place ,you can assign to variable in controller
You should check in the controller whether data has been entered or not. If not, then return the null for $transactions.
public function index(Request $request)
{
if(count($request->all()) > 0) {
$transactions = UserTransaction::query();
$userId = request()->get('userId');
$price = request()->get('price');
$type = request()->get('type');
$status = request()->get('status');
$ordering = request()->get('ordering');
if($userId){
$transactions->where('userId' , $userId);
}
if ($price) {
$transactions->where('price' , $price);
}
if ($type) {
$transactions->where('type' , $type);
}
if ($status) {
$transactions->where('status' , $status);
}
$transactions= $transactions->paginate(5)->appends($request->except('page'))
} else {
$transactions = null;
}
return view('admin.transaction.index',[
'transactions' => $transactions,
'stats' => $stats
]);
}
Then in your view just check $transactions->count() > 0

Sort by relationship first in laravel

I have two tables: admins and log_doctor_infos. admins table has relationship hasOne with log_doctor_infos throught doctor_id like this.
In model Admin:
public function logDoctorInfo() {
return $this->hasOne(LogDoctorInfo::class, 'doctor_id', 'id');
// Model LogDoctorInfo is log_doctor_infos table
}
And in Model LogDoctorInfo:
public function doctor(){
return $this->belongsTo(Admin::class, 'doctor_id', 'id');
// Model Admin is admins table
}
I get all data form admins table and i want to sort record has relationship with log_doctor_infos to top.
Yellow record, which has relationship with log_doctor_infos and i want to sort it in top.
Edit: i use paginate in this query and i really want to get quantity of Yellow record.
Thanks for reading!
In my controller, i have custom filter and paginate. Help me.
public function index(Request $request) {
$fullname = $request->query('fullname', NULL);
$phone = $request->query('phone', NULL);
$status = $request->query('status', NULL);
$doctors = (new Doctor)->newQuery();
if ($fullname != NULL) {
$doctors = $doctors->where('fullname', 'LIKE', '%'.$fullname.'%');
}
if ($phone != NULL) {
$doctors = $doctors->where('phone', 'LIKE', '%'.$phone.'%');
}
if ($status != NULL) {
$doctors = $doctors->where('status', $status);
}
$doctors = $doctors
// ->with(array('logDoctorInfo' => function($query) {
// $query->orderBy('updated_at', 'ASC');
// }))
->latest()
->paginate()
->appends([
'fullname' => $fullname,
'phone' => $phone,
'status' => $status
]);
// dd($doctors);
return view('admin.doctors.index', compact('doctors'));
}
you can use the withCount method.
Admin::withCount('logDoctorInfo')
->orderBy('log_doctor_info_count', 'desc')
->paginate(5);
Your controller will look like this
public function index(Request $request) {
$fullname = $request->input('fullname', NULL);
$phone = $request->input('phone', NULL);
$status = $request->input('status', NULL);
$doctorQuery = Doctor::query();
if ($fullname) {
$doctorQuery->where('fullname', 'LIKE', '%'.$fullname.'%');
}
if ($phone) {
$doctorQuery->where('phone', 'LIKE', '%'.$phone.'%');
}
if ($status) {
$doctorQuery->where('status', $status);
}
$doctorQuery->withCount('logDoctorInfo')
->orderBy('log_doctor_info_count');
$doctors = $doctorQuery->paginate()
->appends([
'fullname' => $fullname,
'phone' => $phone,
'status' => $status
]);
// dd($doctors);
return view('admin.doctors.index', compact('doctors'));
}
Doctor::with('logDoctorInfo')->get()->sortByDesc('logDoctorInfo.id');

How to use "With" in subqueries laravel eloquent with condition?

I am trying to add new functionality to my project to be able to add tweet anonymously so I need to check if the public field = 0 , return the tweets without user or null user object !
How I can use "with" with OrWhere or something like that?
I have done that by merging the collections but I need more efficient query to do that
when I try OrWhere()->with() that return user data for all collection I need the data in with() comes only with condition ? how to do that ?
Thanks
$tweets = Tweet::where(function ($query) {
$query->where('public',1);
$query->where('hashtag_id', request('hashtag_id'));
})->with([
'user' => function ($query) {
$query->select('id', 'name', 'username', 'photo', 'verified')->withTrashed();
},
'hashtag' => function ($query) {
$query->withTrashed();
},
])-> where(function ($query) {
$query->whereRaw('DATE_ADD(created_at,INTERVAL expiration_time SECOND) >= "' . Carbon::now()->toDateTimeString() . '" or expiration_time = 0');})
->withCount(['replies'])->orderBy('created_at', 'desc')->get();
$tweets2 = Tweet::where(function ($query) {
$query->where('public',0);
$query->where('hashtag_id', request('hashtag_id'));
})->with(['hashtag' => function ($query) {
$query->withTrashed();
},
])-> where(function ($query) {
$query->whereRaw('DATE_ADD(created_at,INTERVAL expiration_time SECOND) >= "' . Carbon::now()->toDateTimeString() . '" or expiration_time = 0');})
->withCount(['replies'])->orderBy('created_at', 'desc')->get();
$tweets = $tweets->merge($tweets2);
I have figured this solution by adding method in the model check this condition and return depends on this condition
$tweets = Tweet::Where(function ($query) {
$query->where('hashtag_id', request('hashtag_id'));
})->with([
'hashtag' => function ($query) {
$query->withTrashed();
},
])->where(function ($query) {
$query->whereRaw('DATE_ADD(created_at,INTERVAL expiration_time SECOND) >= "' . Carbon::now()->toDateTimeString() . '" or expiration_time = 0');})
->withCount(['replies'])->orderBy('created_at', 'desc')->get();
foreach($tweets as $tweet){
$tweet->user = $tweet->GetPublic();
}
That is the method in the model
public function GetPublic()
{
if($this->public == 1)
{ $user = $this->user;
return $user;
}
else{
return null;
}
}

Combine multiple queries (Laravel 5)

I try to make a search engine for users. The search will be with multiple fields so as the user can be selecting whatever he want and get the result.
routes.php:
Route::get('search/{tag?}/{town?}/{education?}/{contract?}', 'DisplayJobs#getSearch');
DisplayJobs.php Controller
public function getSearch($tag = null, $town = null, $education = null, $contract = null)
{
//get already database values to send them to the form
$tags = \App\Tag::lists('name', 'id');
$contract = \App\Contract::lists('name', 'id');
$towns = \App\Town::lists('name', 'id');
$education = \App\Education::lists('name', 'id');
$tagQueryBuilder = Tag::query();
$townQueryBuilder = Town::query();
$educationQueryBuilder = Education::query();
$contractQueryBuilder = Contract::query();
if(Input::has('tag'))
{
$tagQueryBuilder->TagOfUser(Input::get('tag'));
}
if(Input::has('town'))
{
$townQueryBuilder->TownOfUser(Input::get('town'));
}
if(Input::has('education'))
{
$educationQueryBuilder->EducationOfUser(Input::get('education'));
}
if(Input::has('contact'))
{
$contractQueryBuilder->ContactOfUser(Input::get('contact'));
}
return view('main.search_jobs', compact('tags', 'towns', 'contract', 'education'));
}
If I try with each single query it works perfectly but I want to combined result data from all the queries or a way to query all the data at once.
In each model I have my query scope like this (Tag.php) Model:
public function jobs()
{
return $this->belongsToMany('App\Job');
}
public function scopeTagOfUser($query, $tag)
{
return $query->where('id', '=', $tag)->with('jobs');
}
After a lot of hours I found a solution. I will post it below so if anyone has the same problem can see one solution.
First I have delete all of the scope queries in the models and all of the work completed to the controller like bellow:
public function getSearch($tag = null, $town = null, $education = null, $contract = null)
{
//get already database values to send them to the form
$tags = \App\Tag::lists('name', 'id');
$towns = \App\Town::lists('name', 'id');
$contract = \App\Contract::lists('name', 'id');
$education = \App\Education::lists('name', 'id');
//get inputs from users
$getTagFromUser = Input::get('tag');
$getTownFromUser = Input::get('town');
$getContractFromUser = Input::get('contract');
$getEducationFromUser = Input::get('education');
$tagQuery = DB::table('jobs')
->join('job_tag', 'jobs.id', '=', 'job_tag.job_id')
->join('tags', 'job_tag.tag_id', '=', 'tags.id')
->where('tags.id', '=', $getTagFromUser);
$townQuery = DB::table('jobs')
->join('job_town', 'jobs.id', '=', 'job_town.job_id')
->join('towns', 'job_town.town_id', '=', 'towns.id')
->where('towns.id', '=', $getTownFromUser);
$contractQuery = DB::table('jobs')
->join('job_contract', 'jobs.id', '=', 'job_contract.job_id')
->join('contracts', 'job_contract.contract_id', '=', 'contracts.id')
->where('contracts.id', '=', $getContractFromUser);
$educationQuery = DB::table('jobs')
->join('job_education', 'jobs.id', '=', 'job_education.job_id')
->join('education', 'job_education.education_id', '=', 'education.id')
->where('education.id', '=', $getEducationFromUser);
$finalQuery = $tagQuery->union($townQuery)->union($contractQuery)->union($educationQuery)->get();
return view('main.search_jobs', compact('tags', 'towns', 'contract', 'education', 'finalQuery'));
}

Laravel search in 2 models with one Query search in Model1 and check a status of Model2

I have two Models: Trade and User
a user has a status(bool) = 1 or 0 when i search in the Trade Model i want check has the User in the User Model status = 1 and only show this results
models\User.php:
public function Trade()
{
return $this->hasMany('Trade', 'user_id')
->orderBy('created_at', 'desc');
}
models\Trade.php:
public function User()
{
return $this->belongsTo('User', 'user_id');
}
In the TradeController.php function:
public function getSearch()
{ //League must be selected
$query = Trade::where('league_id', '=', Input::get('league'))->with('User')->open();
$query->where(function ($query) {
//Check if Offer selected add clausel
if ($orb1 = Input::get('orb1')) {
$query->where('orb1_id', '=', $orb1);
}
//Check if I want to Buy Selecet add clausel
if ($orb2 = Input::get('orb2')) {
$query->where('orb2_id', '=', $orb2);
}
Now i have a Checkbox called "online" if this checkbox checked i want to get all Trades where the User status = 1
/******************************************************************************************************
//If Checkbox 'online' check get only results with Online Users (status = 1) in the Users Table
******************************************************************************************************/
if (Input::get('online')) {
$query->where('users.status', '=', 1);
}
});
At the end of the function is check has query some results and put the results to the view:
if ($query->count() > 0) {
$trades = $query->paginate(40)->appends(array_except(Input::query(), Paginator::getPageName()));
return View::make('trade.trade_table', compact('trades'));
} else {
return Redirect::to('trades')->with('error', 'No Results found');
}
}
}
Here a paste: http://paste.pm/d4b.js
thanks :D
i found a answer dont know if the best but works
public function getSearch()
{
$league_id = Input::get('league');
$orb1_id = Input::get('orb1');
$orb2_id = Input::get('orb2');
$is_online = Input::get('online');
$query = DB::table('trades');
$query->join('users', 'trades.user_id', '=', 'users.id');
$query->where('trades.expires_at', '>', Carbon::now());
$query->where('trades.league_id', '=', $league_id);
$query->join('ladders', 'trades.league_id', '=', 'ladders.id');
$query->select('trades.id',
'ladders.name',
'trades.user_id',
'trades.orb1',
'trades.orb2',
'trades.much1',
'trades.much2',
'trades.expires_at',
'trades.report',
'users.ingame',
'users.username',
'users.status');
if ($orb1_id) {
$query->where('trades.orb1_id', '=', $orb1_id);
}
if ($orb2_id) {
$query->where('trades.orb2_id', '=', $orb2_id);
}
if ($is_online) {
$query->where('users.status', '=', 1);
}
$trades = $query->paginate(4)->appends(array_except(Input::query(), Paginator::getPageName()));
return View::make('trade.results', compact('trades'));
}

Categories