I want to create leftjoin with pagination on laravel.
how to create pagination with leftjoin ?
Here my code :
$news = News::leftJoin('categories','news.category_id', '=', 'categories.id')
->select('news.*' ,'categories.category')
->get()->sortByDesc('created_at');
Previously, i use $news = News::paginate(10); and its works, but it without leftjoin.
and here my html code to create pagination
{{$news->links('vendor.pagination.pagination')}}
The paginate function should be done on the Query Builder object, not on the collection returned by get().
$news = News::leftJoin('categories','news.category_id', '=', 'categories.id')
->select('news.*' ,'categories.category')
->paginate(10);
The same goes for sorting. When you call get()->sortByDesc(), you are getting a Collection then sorting the collection through PHP. Normally, you would want to use orderBy() in the query builder to sort through SQL.
$news = News::leftJoin('categories','news.category_id', '=', 'categories.id')
->select('news.*' ,'categories.category')
->orderBy('created_at', 'DESC')
->paginate(10);
Use Eloquent: Relationships
For example:
News.php model
class News extends Model
{
protected $primaryKey = 'id';
function withCategories() {
return $this->hasOne('App\Categories', 'id', 'category_id');
}
public function list(){
News::with('withCategories')->orderBy('created_at', 'DESC')
->paginate(10);
}
}
in news.blade.php (example)
<table>
<tbody>
#foreach ($news as $news)
<tr>
<th>{{ $news->id }}</th>
<td>{{ $news->title }}</td>
<td>{{ $news->withCategories->title }}</td> <!-- Category name-->
</tr>
#endforeach
</tbody>
</table>
</div>
Related
I have two table as you can see that relations each other.
I want to see this table
How to do that in my blade file or controller.
this is my blade file;
#foreach ($costs as $cost)
#foreach ($projects as $project)
#if($project->id == $cost->project_id)
<tr class="odd">
<td>{{ $project->id }}</td>
<td>{{ $cost->price }}</td>
</tr>
#endif
#endforeach
#endforeach
public function tablo1()
{
$costs = DB::table('cost_manages')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('projects')
->whereColumn('projects.id', 'cost_manages.project_id')->groupBy('project_id');
})
->get();
$projects = DB::table('projects')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('cost_manages')
->whereColumn('cost_manages.project_id', 'projects.id');
})
->get();
return view('home.muhasebe_Tablo1', [
'costs' => $costs,
'projects' => $projects
]);
}
That one is my controller.
There are 2 costs for project number 11. I want to write a single record by collecting them.
Please help me
Use join:
DB::table('projects')
->leftjoin('cost_manages', 'projects.id','const_manages.project_id')
->select('projects.id as id', 'projects.name as name', 'cost_manages.cost as cost')->get()
and then loop through this.
I have the following tables:
users: id, name, ...
companies: id, name, ...
I have a scope with a LIKE operator, And I use it to search in both users.name and companies.name as follows:
public function scopeSearch(Builder $query, string $term = null)
{
$query->join('companies', 'companies.id', '=', 'users.company_id');
$term = $term.'%';
$query->where('users.name', 'like', $term)
->orWhere('companies.name', 'like', $term);
}
Action:
$users = User::query()
->search($request->input('q'))
->with('company')
->paginate();
// ...
Since name was used in both tables, Laravel can't distinguish between them, so it ends up filling the users.name with a companies.name:
The view looks like this:
#foreach($users as $user)
// ...
<th scope="row">{{ $user->id }}</th>
<td>{{ $user->name }}</td> // wrong: this gives the company.name
<td>{{ $user->company->name }}</td>
<td>{{ $user->email }}</td>
// ...
#endforeach
One solution to solve this is by using select and some aliases, but that would be a nasty solution.
Any good solution?
Update 1: I don't want to use whereHas since it's slower than joining when it comes to using the LIKE operator.
Update 2: another solution is to alias the companies.name and the users.name as follows:
public function scopeSearch(Builder $query, string $term = null)
{
$query->join('companies', 'companies.id', '=', 'users.company_id')
->select(['*', 'companies.name as company_name', 'users.name as user_name']);
}
<td>{{ $user->user_name }}</td>
<td>{{ $user->company_name }}</td>
This works fine, but if (for any reason) I want to get rid of the searching capability, I also need to modify the view, so a dependency has been introduced here.
I would probably rewrite the search-scope to search for the company name through relations and using whereHas(), instead of joining it in. That way you never have ambiguous column names when using that scope.
It would generate a different query, but you would end up with the same result.
public function scopeSearch(Builder $query, string $term = null)
{
$term = $term.'%';
return $query->where('name', 'like', $term)
->orWhereHas('company', function($query) use ($term) {
return $query->where('name', 'like', $term);
});
}
After doing some experiments, I found that using the whereIn clause is faster and more convenient than using join/whereHas:
$query->where('name', 'like', $term)
->orWhereIn('company_id', function($query) use ($term) {
$query->select('id')->from('companies')->where('name', 'like', $term);
});
The action remains the same:
<td>{{ $user->name }}</td>
<td>{{ $user->company->name }}</td>
And as I said it's much faster than joining and whereHas.
Here is my benchmark:
600ms: whereHas.
500ms: join.
130ms: whereIn.
I'm trying to make an admin page where the owner of the store can check the info from users that singed on the website, but I always get the Undefined property: stdClass::$name error
Here's the controller function:
public function listar(){
$users = DB::table('users')->select('name')->orderBy('updated_at', 'desc')->get();
$users = DB::table('users')->select('email')->orderBy('updated_at', 'desc')->get();
$users = DB::table('users')->select('phone')->orderBy('updated_at', 'desc')->get();
}
Here's part of the form:
#foreach ($users as $u)
<tr>
<td>{{ $u->name }}</td>
<td>{{ $u->email }}</td>
<td>{{ $u->phone}}</td>
</tr>
#endforeach
I just want it to be able to show this info from the database.
You're actually running the query three separate times, overwriting the $users variable each time. You end up with the last one, and it doesn't have a name property because you only selected phone. You should run it just once and specify all the columns you want in select().
public function listar(){
$users = DB::table('users')->select('name', 'email', 'phone')
->orderBy('updated_at', 'desc')->get();
}
public function listar(){
$users = //Your user model class ::all();
return $users;
}
Then try to view
#foreach ($users as $u)
<tr>
<td>{{ $u->name }}</td>
<td>{{ $u->email }}</td>
<td>{{ $u->phone}}</td>
</tr>
#endforeach
I have several row in a table in db and every row related with three tables and every table has many rows. when i loop main table rows i also loop three tables rows now if one of tables has a content in row then i want to prevent showing entire sub that loop only which contain a value.
In my controller:
public function classWiseResult(Request $request){
$students = Students::where('class',$request->class)
->with('firstTerm')
->with('secondTerm')
->with('finalTerm')
->get();
return view('admin.showResult.show',compact('students'));
}
in my view:
#foreach($students as $student)
<tr>
<td>{{$student->id}}</td>
<td>{{$student->fname}}</td>
<?php $Ftotal = 0; $Fcount = 0; ?>
#foreach($student->firstTerm as $first)
<?php $Fcount++;?>
<?php $Ftotal += gradePoint($first->number); ?>
#endforeach
<?php $fttp = gpa($Ftotal, $Fcount) ;?>
<td>{{$fttp}}</td>
<td>
#if($Ftotal){
{letterGrade(gpa($Ftotal, $Fcount))}
}
#endif
</td>
Result:
I want to skip showing result if I have a subject number under 32
This method uses relationship count comparison.
Controller
public function classWiseResult(Request $request){
$students = Students::where('class',$request->class)
->withCount(['firstTerm as firstTermPromoted' => function($q) {
$q->where('number', '>', 32);
}])
->withCount('firstTerm as firstTermAllCount')
->withCount(['secondTerm as secondTermPromoted' => function($q) {
$q->where('number', '>', 32);
}])
->withCount('secondTerm as secondTermAllCount')
->withCount(['finalTerm as finalTermPromoted' => function($q) {
$q->where('number', '>', 32);
}])
->withCount('finalTerm as finalTermAllCount')
->with('firstTerm')
->with('secondTerm')
->with('finalTerm')
->get();
return view('admin.showResult.show',compact('students'));
}
In your view you can compare the total count of all relations and count of relations that passes the condition.
View
#foreach($students as $student)
#if($student->firstTermPromoted == $student->firstTermAllCount
&& $student->secondTermPromoted == $student->secondTermAllCount
&& $student->finalTermPromoted == $student->finalTermAllCount)
{{ "Promoted" }}
#else
{{ "Not Promoted" }}
#endif
#endforeach
I'm not using eloquent, my models are like this.
class drivers extends Model
{
}
I want to display records of all drivers ( one record in each row )
My driver table has field (driver_id,name,tyre_id)
My tyre table has field (id, title)
My bank table has field (id, driver_id, bank)
I want my record to be like this...
Driver Id, Name, Bank Details, Tyre Title
100000111, Ayer, Available, GO
.. so on
For bank details if driver_id has a record in bank table, it should display available otherwise N/A.
$drivers= Drivers::get();
$myarray = ();
foreach ($drivers as $d){
$bank = Bank::where('driver_id',$d->driver_id)->first();
$tyre = Tyre::where('id',$d->tyre_id)->first();
$myarray[] = $d->driver_id;
$myarray[] = $d->name;
$myarray[] = isset($bank) ? "available" ; '';
$myarray[] = $tyre->title;
}
This is what i have tried, I'm to new to laravel, how can i achieve this in laravel or using query like DB Table?
Laravel offers two very useful tools for performing database operations eloquent and query builder. It is advisable to work as much as possible with eloquent and their relationships as it facilitates much of the common operations that we normally need to perform.
Now, if you want to make more complex queries you can use query builder, also, an example of your case using query builder would be something like this:
In your controller you make the query and pass the data to view:
$data = DB::table('driver')
->leftJoin('bank', 'bank.driver_id','=', 'driver.driver_id')
->join('tyre', 'tyre.id','=', 'bank.tyre_id')
->select('driver.driver_id as id',
'driver.name',
'bank.id as bank_id',
'tyre.title')
->groupBy('driver.driver_id')
->get()
And in your view you can use a foreach loop to display the data (and you can use a conditional to display the bank field):
<table>
<thead>
<tr>
<th>Driver ID</th>
<th>Name</th>
<th>Bank Detail</th>
<th>Tyre Title</th>
</tr>
</thead>
<tbody>
#foreach($data as $item)
<tr>
<td>{{ $item->id }}</td>
<td>{{ $item->name }}</td>
<td>{{ isset($item->bank_id) ? "availible":"N/A" }}</td>
<td>{{ $item->title }}</td>
</tr>
#endforeach
</tbody>
</table>
likewise I recommend you read the documentation of eloquent and try to use it.
https://laravel.com/docs/5.5/queries
https://laravel.com/docs/5.5/eloquent
The Good way to Solve this is laravel relations
here the link
laravel documentation
Select your driver table as base table and use relations to get the other table fields;
array_push() function to push values to array
Another way is using DB Facade with joins: Like this:
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();