hello I'm trying to fetch one to many data in view like post with this feast comment shooed be show in view
iam able to get value in array now i what to show in view
my array controller
public function data($id)
{
$post= User::with(['Comments'=>function($query){
$query->first();
}])->find($id);
dd($post->toArray());
}
array data
array:53 [▼
"id" => 39
"name" => "KUMAR"
"post" => "hello word "
"created_at" => "2022-02-11T02:38:51.000000Z"
"updated_at" => "2022-02-11T10:05:26.000000Z"
"comments" => array:1 [▼
0 => array:13 [▼
"id" => 6
"user_id" => "39"
"comment" => "good post"
"created_at" => "2022-02-11T15:13:51.000000Z"
"updated_at" => "2022-02-11T15:13:51.000000Z"
]
]
]
my view Controller
public function data($id)
{
$post= User::with(['Comments'=>function($query){
$query->first();
}])->find($id);
return view('user.post',compact('post'));
}
So your User model already has this comments relationship
public function comments()
{
return $this->hasMany(Comment::class);
}
You can add this firstComment relatioship
public function firstComment()
{
return $this->hasOne(Comment::class)->oldest(); // or ->latest()
}
Then fetch your User this way
$post = User::with(['firstComment'])->find($id);
dump($post);
dd($post->firstComment);
Try this
public function data($id)
{
$post= User::wherehas('Comments', function($query){
$query->where('user_id',$id);
})->get();
return view('user.post',compact('post'));
}
Query to get monthly orders (total orders per month(count) or total sales per month(sum)):
Tried this query, but it is not working. Also tried with other results from StackOverflow, but I didn't understand how it is done with MongoDB query. This is the link to that question : select-sum-column-and-group-by-with-mongodb-and-laravel
$monthly_orders = Order::select(
DB::raw('sum(total_amount) as sum'),
DB::raw('YEAR(created_at) year, MONTH(created_at) month'),
)
->groupBy('month')
->get();
When I try to get total amount by using group by customer ID , it is returning sum as null
$monthly_orders = Order::selectRaw('sum(total_amount) as sum, customer_id')
->groupBy('customer_id')
->pluck('sum', 'customer_id');
Result :
Illuminate\Support\Collection {#2123 ▼
#items: array:4 [▼
"6098e5ff5977a25ee96a2a42" => null
"60dbf87f7d8ffb7cdb2233d2" => null
"605af409195d8e59e34893f2" => null
"60ddae4a66fb69678e45f056" => null
]
}
Try using raw and aggregate
$monthly_orders = Order::raw(function ($collection) {
return $collection->aggregate([
[
'$group' => [
"_id" => '$customer_id',
'customer_id' => ['$first' => '$customer_id'],
'sum' => ['$sum' => '$total_amount']
]
],
]);
});
you can use pluck
$monthly_orders->pluck('sum','customer_id')
Group by month
$monthly_orders = Order::raw(function ($collection) {
return $collection->aggregate([
[
'$group' => [
"_id" => ['$month'=>'$created_at'],
'customer_id' => ['$first' => '$customer_id'],
'sum' => ['$sum' => '$total_amount']
]
],
]);
});
I have 2 collections as below:
$unpaid = WhmcsClientsInvoice::join('quotations', 'quotations.id', 'whmcs_clients_invoices.quotation_id')
->select('whmcs_clients_invoices.invoice_id AS id', 'whmcs_clients_invoices.invoice_date AS date', 'quotations.total AS amount', 'whmcs_clients_invoices.payment_due_date AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('whmcs_clients_invoices.invoice_date', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach($unpaid as $un) { $un['type'] = "invoice"; }
$paid = InvoiceHistory::join('whmcs_clients_invoices', 'whmcs_clients_invoices.id', 'invoice_history.whmcs_clients_invoices_id')
->select('invoice_history.id', 'invoice_history.date_paid AS date', 'invoice_history.amount_paid AS amount', 'invoice_history.created_at AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('invoice_history.date_paid', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach ($paid as $paid) { $paid['type'] = 'payment'; }
$trans = $unpaid->merge($paid);
dd($trans);
But when I try to merge these 2 collections, an error will occur.
I tried $transaction = $unpaid->union($paid)->sortBy('date'); but to no avail. Vardump of the merged collection shows:
error_log the $transaction would show something like this:
{"date":"2021-01-26
00:00:00","id":12,"amount":111.3,"due_date":"2021-01-26
09:00:05","type":"payment","0":{"id":1,"date":"2021-01-07","amount":222.6,"due_date":"2021-01-14","type":"invoice"},"1":{"id":3,"date":"2021-01-09","amount":6572,"due_date":"2021-01-16","type":"invoice"},"2":{"id":4,"date":"2021-01-12","amount":148.4,"due_date":"2021-01-19","type":"invoice"},"3":{"id":5,"date":"2021-01-12","amount":144.16,"due_date":"2021-01-19","type":"invoice"},"4":{"id":6,"date":"2021-01-16","amount":24.38,"due_date":"2021-01-23","type":"invoice"},"5":{"id":2,"date":"2021-01-29","amount":222.6,"due_date":"2021-01-14","type":"invoice"},"6":{"id":24,"date":"2021-02-23","amount":190.8,"due_date":"2021-03-02","type":"invoice"}}
Apparently the union merge the 2 collections, but couldn't assign key to the first item...
How do I merge 2 collections without missing any records in both collections? The expected output should be from this:
Collection {#595 ▼
#items: array:3 [▼
0 => WhmcsClientsInvoice {
"id" = 37
"date" => "2021-02-07 00:00:00"
"amount" => 50.0
"due_date" => "2021-02-07 14:19:20"
"type" => "payment"
}
2 => InvoiceHistory {
"id" = 37
"date" => "2021-02-07 00:00:00"
"amount" => 50.0
"due_date" => "2021-02-07 14:19:20"
"type" => "payment"
}
1 => WhmcsClientsInvoice {
"id" = 37
"date" => "2021-02-07 00:00:00"
"amount" => 50.0
"due_date" => "2021-02-07 14:19:20"
"type" => "payment"
}
]
}
This happens sometimes,
Try this
$trans = $unpaid->concat($paid);
After a few days of painstaking research, I found a way that works for me. This is my updated code:
$transaction = collect(new WhmcsClientsInvoice);
$unpaid = WhmcsClientsInvoice::join('quotations', 'quotations.id', 'whmcs_clients_invoices.quotation_id')
->select('whmcs_clients_invoices.invoice_id', 'whmcs_clients_invoices.invoice_num', 'whmcs_clients_invoices.invoice_date AS date', 'quotations.total AS amount', 'whmcs_clients_invoices.payment_due_date AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('whmcs_clients_invoices.invoice_date', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach($unpaid as $un) {
$un['type'] = "invoice";
$transaction->push($un);
}
$paid = InvoiceHistory::join('whmcs_clients_invoices', 'whmcs_clients_invoices.id', 'invoice_history.whmcs_clients_invoices_id')
->select('invoice_history.date_paid AS date', 'invoice_history.remark', 'invoice_history.amount_paid AS amount', 'invoice_history.created_at AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('invoice_history.date_paid', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach ($paid as $pa) {
$pa['type'] = "payment";
$transaction->push($pa);
}
$transaction = $transaction->sortBy('date');
First, I make an empty collection based on WhmcsClientInvoices called Transaction. Basically, my idea is to create 2 separate collections, then merge them into Transaction. So, I made 2 eloquents to get 2 different collections. Then, during the foreach, I added a new item with key call type, to differentiate whether each record is invoice or payment. Then, I take each individual record in collection and push it to Transaction. I repeat the process with $paid collection. Lastly, I sort the collection by date.
This is driving me crazy.
I have two tables: Records and Users and a query to bring records of users:
$records = Record::with('user')
->join('users', 'users.id', '=', 'records.user_id')
->orderBy('users.name', 'asc')
->where('schedule_id', $schedule->id)
->get();
The dd($records); brings me this:
Collection {#827 ▼
#items: array:6 [▼
0 => Record {#773 ▼
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:13 [▼
"id" => 26
"user_id" => 26
"schedule_id" => 3
"start_time" => "12:00"
"end_time" => "20:00"
"created_at" => null
"updated_at" => null
"name" => "Ali Fay"
"email" => "twolff#gmail.com"
"password" => ""
"role_id" => 6
"store_id" => 3
"remember_token" => null
]
As you can see, the attributes are ok of both models except the "id", that is the id of the user, not the record. What I'm doing wrong?
The concrete problem is this case, that you have two columns named id in the join, so select the columns you need and only select one of the ids, can probaly easily be solved by this, and if columns of the user is needed you can select them as wanted.
$records = Record::with('user')
->join('users', 'users.id', '=', 'records.user_id')
->orderBy('users.name', 'asc')
->where('schedule_id', $schedule->id)
->select('records.*')
->get();
The best solution is to use relationships, so if the model is something similar to.
public class record
{
public function user() {
return $this->belongsTo('App\User');
}
}
Then you instead can do the same query as. WhereHas checks if the relation with the given condition exists, otherwise if there was no condition, has could have been used.
Record::whereHas('user', function ($query) use($schedule){
$query->where('schedule_id', $schedule->id);
})->get()->sortBy(function($item, $key) {
return $item->user->name;
});
You don't need to use join() here:
$records = $schedule->records()->with('user')->get();
Then sort the collection:
$records->sortBy(function($i) {
return $i->user->name;
});
I get a Collection from a Query in Laravel.
Actually, I'm processing collection like that:
foreach ($cts as $ct) {
$array[$ct->id] = $ct->category->name;
}
It outputs this:
array:2 [▼
1158 => "Junior por Equipo"
1160 => "Varonil por Equipo"
]
Now, I would like to user map() function over muy collection as I like it better:
MyModel::get()
->get()
->map(function ($item, $value){
return [ $item->id => $item->category->name ];
})->toArray();
But now, I get :
array:2 [▼
0 => array:1 [▼
1158 => "Junior por Equipo"
]
1 => array:1 [▼
1160 => "Varonil por Equipo"
]
]
How should I do to output it like the first case?
You don't have to map the collection, just use MyModel::lists('name', 'id' ) ;
There is a collection method for that. pluck() and eloquent lists()
no its preferred to use pluck for getting some columns only. previously lists() was used.
see https://laravel.com/docs/5.3/collections#method-pluck
as the document says
The pluck method retrieves all of the values for a given key/keys only
so it would be something like this.
Model::get()->pluck('name','id);
Than you can do toArray() on the result if you want to get an array instead of a collection.