Can't view collection of data in laravel - php

i returned a collection of two tables of data with join query as a collection and group by user id. i want to view it on a html table.
My data array looks like this. How can i show this all data into html table view using laravel blade.

if you are sending the collection to your blade template. You can use a foreach loop to iterate through array:
#foreach($items as $item)
<tr>
<td>{{ $item->fname}}</td>
<td>{{ $item->lname }}</td>
</tr>
#endforeach

Related

Dynamic column/attribute. Stuck. Need inspiration

i’m looking for a solution to a problem that I’m having for a while now. Maybe you can inspire me to do this better. I’m trying not to make a basic mistake in the planning process therefore I’m asking you for advice.
I’m having a Contact::model which has few fixed attributes like id etc. Additionally I would like to have different attributes created dynamically for the whole Contact::model. Some user will be given the functionality to add attributes like name, email, address to the whole model. I’ve dropped the idea of programmatically updating the table itself by creating/dropping columns (this would introduce different problems). As for now i've created two additional tables. One with the additional column names [Columns::model] and a pivot table to assign the value to a Contact::model and Column::model.
To list all contacts i’m preparing the ContactColumn table as array where the first key is the contact_id and the second is the column_id, therefore i get the value. This introduces the n+1 issue. This would not be that bad, but with this approach it will be extremely hard (or resource consuming) to order the contacts by dynamic column values, filtering, searching etc.
Can you somehow guide me to a better solution. How can i merge the contact collection with the values for given columns so it looks like it was a fixed table?
<table>
<thead>
<tr>
<th>Fixed columns [i.e. ID]</th>
#foreach ($columns as $column)
<th>{{ $column->name }}</th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($contacts as $contact)
<tr>
<td>{{ $contact->id }}</td>
#foreach ($columns as $column)
<td>
#if (array_key_exists($column->id, $values[$contact->id]))
{{ $values[$contact->id][$column->id] }}
#endif
</td>
#endforeach
</tr>
#endforeach
</tbody>
</table>
And the $value array.
foreach (ColumnContact::all() as $pivot) {
$values[$pivot->contact_id][$pivot->column_id] = $pivot->value;
}
return $values;
Edit: I've solved it like this
$this->contacts = Contact::when($this->dynamicColumnName, function($query) {
$query->join('column_contact', function ($join) {
$join->on('id', '=', 'column_contact.contact_id')
->where('column_contact.column_id', '=', $this->dynamicColumnName->id);
})
->orderBy('value', $this->orderingDirection);
})
(...)
->paginate(self::PER_PAGE);
Apart from the fixed fields, add an extra JSON field in your schema called 'custom_fields'. Have a look into => https://github.com/stancl/virtualcolumn
Separate table for custom fields is not a good idea because then you have to handle model events separately and so on.

How to get all records in laravel Models

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();

Symfony (php) comparison in FindBy statement

I am using Symfony and need to compare to variables from my database called $voorraad and $minimumvoorraad. I need to see the product when $voorraad is lower than $minimumvoorraad. Since I am using Symfony we use the PHP language. I've tried the FindByVoorrad and FindOneBy statements with no success, I only get the header from my twig but that's it.
Thanks in advance.
Given your Entity consists of whatever fields including 'voorraad' and 'minimumvoorraad', you should be able to get your database table's content via
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT e
FROM AppBundle:Entity e
WHERE e.voorraad < e.minimumvoorraad'
);
$products = $query->getResult();
Edit: the e in the query is a SQL-typical alias defined inline.
And then treat your $products variable as usual, where you can use all of your getters and setters.
After rendering and passing your products to the Twig view
return $this->render('view.html.twig', array(
'products' => $products
));
you could then proceed to print the products, for example, in a table inside your Twig view:
<table>
{% for product in products %}
<tr>
<td>{{ product.id }}</td>
<td>{{ product.voorraad }}</td>
<td>{{ product.minimumvoorraad }}</td>
</tr>
{% endfor %}
</table>

Laravel Eloquent: Reduce number of queries

Let's say I have 250 users in users table and each user has one or many books, and each book has one or many chapters. Now I would like to print the user names, with their book names.
Controller:
$users = User::all();
in blade:
#foreach($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>
#foreach($user->books as $book)
{{ $book->name }},
#endforeach
</td>
</tr>
#endforeach
# of queries 252
Now to overcome the n+1 problem, the query should be
$users = User::with('books')->get();
Now the # of queries are only 2.
I want to print the book names with number of chapters like this->
BookName(# of chapters). So in my blade
#foreach($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>
#foreach($user->books as $book)
{{ $book->name }} ({{ $book->chapters->count() }}),
#endforeach
</td>
</tr>
#endforeach
so for 750 books with 1500 chapters the # of queries are about 752 and it increases if chapter number increases.
Is there any better Eloquent way to reduce it or should I go for raw SQL queries?
You don't need to load all chapters data and then manually count each collection. Use withCount() instead:
$users = User::with('books')->withCount('chapters')->get();
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.
From the Eloquent Documentation:
Nested Eager Loading
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$books = App\Book::with('author.contacts')->get();
In your case, you can retrieve the nested relationships you need with the following:
User::with('books.chapters')->get();

How to eliminate duplicate values and format the output from DQL in Twig?

I am working on a reporting application in Symfony2, and my twig file shows the following output using DQL. I created an Entity, passed the values using render from action function to the twig. I used a for loop to display all the elements from an associative array (See picture 1). how do I group the result in this specific format? (See picture 2) such that all the duplicate zoneName and rank are eliminated and placed on the top only once.
Current Display of records in twig FROM DQL
The output which I want to achieve
My query in Action function of controller is as follows
$qb->select('distinct t.zoneName, t.rank, t.actSanctList, t.offDate')
) /*, $dql */
->addGroupBy('t.zoneName')
->addGroupBy('t.rank')
->addGroupBy('t.actSanctList')
->addGroupBy('t.offDate')
->orderBy('t.zoneName', 'ASC')
$DL01 = $qb->getQuery()->getResult();
My twig file
{% for DL01_line in DL01_data %}
<tr>
<td>{{ DL01_line.zoneName }}</td>
<td>{{ DL01_line.rank }}</td>
<td>{{ DL01_line.actSanctList }}</td>
<td>{{ DL01_line.offDate|date('Y-m-d') }}</td>
</tr>
{% endfor %}

Categories