I have two models: Report and User. This is what I have in my User model
public function userReport() {
return $this->hasMany('App\Report', 'user_id','id');
}
And this is in Report model
public function user() {
return $this->hasOne('App\User', 'id', 'user_id');
}
Controller
public function details( $item_id ){
$report = Item::find($item_id)->report;
return view('details', compact('report'));
}
In view
{!! $report->user->name !!}
In view I show all the users who are reported single Item .. which I query by $item_id.
The problem is that if same user is reported single item 1+ time I see this user 1+ time in the table on the page.
Is it possible to somehow grouped by user_id or count the user_id and show User1 ( 4 time reported ) ...? Where should I group them?
Update: users table
id | username | password
reports table
report_id | id | user_id | date
item table
id | user_id | category | date_added | image
Update2: Image of records in db. Here user with user_id=3 has reported item_id=14 total of 14 times. User with user_id=5 has reported same item_id=14 total of 3 times. So I should see on page user_id=3 ( 14 ) and user_id=3 ( 3 ). Instead I see 17 times user_id=3. Bellow are images
And on page
There should be several ways how to solve your problem
One way is (your controller should look like)
public function details( $item_id ){
$report = Item::find($item_id)->report->unique('user_id');
return view('details', compact('report'));
}
Second way should be to use #foreach in view and there check for unique values.
Third way should be to use foreach in controller and prepare unique data with calculated summarizes inside controller and then pass that prepared data to view.
Which soulution you want to use is just a matter of choice.
Hope it helps you
Just try this. Hope it helps
Report::where('item.id', $item_id)
->select('item.*','users.*',DB::raw('count(reports.report_id) as total'))
->join('item', 'item.id', '=', 'reports.id')
->join('users', 'users.id', '=', 'reports.user_id')
->groupBy('reports.report_id','reports.id')
->get();
Related
I want to user orders data by specific month in a year.
Here is my order Table
id | user_id | price | quantity | total
Here is my order model
public function user() {
return $this->belongsTo(User::class);
}
Here is my user model
public function orders(){
return $this->hasMany(Order::class);
}
In a controller, by doing this I get all user orders
$user= User::with('orders')->get();
dd($user->orders);
Now, How can I get specific month user orders detail?
I want to show all user list with their order's total amount by month.
Try this to get users with their orders' total of September:
$users = User::withSum(['orders as september_total' => function ($query) {
$query->whereMonth('created_at', '9'); // September
}, 'total'])->get();
This will place a september_total attribute on your resulting models.
Take a look at these two queries:
$users = User::query()->with(['orders' => function($q){
$q->whereRaw('MONTH(orders.created_at) = 2');
}])->get();
// eager load all orders that have been created on month 2
$users = User::query()->whereHas('orders', function($q){
$q->whereRaw('MONTH(orders.created_at) = 2');
})->get();
// you'll get all users with orders on month 2 (no eager loading)
You can of course combine with (eager load) and whereHas (filter users) in order to "only get the users that have orders on month 2 AND eager load those orders".
Of course, feel free to use another column (e.g. ordered_at) or change the month if you need to.
I have this database structure
table users table office_user table offices
----------- ----------------- -------------
id * id * id *
full_name user_id name
office_id
joined_at
So in my project every office has many users and user can be joined to many offices in date (joined_at)
User.php model
public function offices()
{
return $this->belongsToMany('App\Office)->withPivot('joined_at');
}
Office.php model
public function users()
{
return $this->belongsToMany('App\User)->withPivot('joined_at');
}
OfficeController.php
public function show(Office $office)
{
$users = User::with(array('phones', 'offices' , function($query)
{
$query->orderBy('joined_at', 'desc');
}))->get();
return view('dashboard.offices.show', compact(['office', 'users']));
}
I need two things :
1- Get current users list for every office
2- Count of current users in every office
I already achieve this:
<h3>{{ $office->name }}</h3><span>{{ $office->users->count() }}</span>
#foreach ($office->users as $user)
<li>{{ $user->full_name }}</li>
#endforeach
But the result is not as expected it gives me all users in certain office and count of them regardless there joined date
I want the list of last joined users to this office and count of them according joined_at field in pivot table
Thank you and Sorry for my english
But the result is not as expected it gives me all users in certain office and count of them regardless there joined date
When you do $office->users->count() that is the expected behavior because you are retrieve all the associated users of every office at any time, so given that you returned all this users, the count() executed in the collection will count all of them.
Your pivot attribute is just a timestamp, so how would you reduce the number of users returned? users that joined the office today/in the last hour/in the last 15 min maybe?
If so, you can add constrains to your count() method to get the results you want.
As an example, in the following lines we are gonna constraint the associated offices that has a joined_at that belongs to today:
public function show(Office $office)
{
$users = User::with([
'phones',
'offices' => function ($offices) {
$offices->whereDate('joined_at', '>', now()->startOfDay());
},
])->get();
return view('dashboard.offices.show', compact([office, 'users']));
}
Check this section of the documentation:
Constraining Eager Loads
Sometimes you may wish to eager load a relationship, but also specify
additional query conditions for the eager loading query. Here's an
example:
$users = App\User::with(['posts' => function ($query) {
$query->where('title', 'like', '%first%');
}])->get();
In this example, Eloquent will only eager load posts where the post's
title column contains the word first. You may call other query
builder methods to further customize the eager loading operation:
$users = App\User::with(['posts' => function ($query) {
$query->orderBy('created_at', 'desc');
}])->get();
I have two items in a table called products with id's 1 and 2. There is a table called invite which has foreign key product_id for products.
In my controller below, i am trying to count the number of product id's that is existing in the invite table.
eg
Product invite
id name id token product_id user_id
1 cal 1 ..d 1 2
2 del 2 dd.. 2 2
3 mac 3 ..gh4 2 2
As above, id's 1 and 2 exist in the invite table. meaning the total count is 2 (although product id 2 appears twice.
When i run my code below, i get a count of 1 instead of 2. What could i be missing out, please?
NB: in this case, i am user just one user
Controller
public function dashboard()
{
$products = Products::orderBy('created_at', 'desc')
->where('user_id', Auth::user()->id)->get();
$get_products_id = [];
foreach($products as $product){
$get_products_id[] = $product->id;
}
$implode_data = implode(',',$get_products_id);
$count_existing_products =
Invite::where('product_id',$implode_data)
->where('user_id', Auth::user()- >id)->get()->count();
return view('dashboard', compact('count_existing_products'));
}
View
<h1>{{count_existing_products}}}</h1>
For WHERE IN clause laravel uses special whereIn() method where you pass array, not string. So, your query becomes:
Invite::whereIn('product_id', $get_products_id)
->where('user_id', Auth::user()->id)
->distinct() // added `distinct` call to get distinct values
->get()
->count();
If distinct does not work, try to groupBy:
Invite::whereIn('product_id', $get_products_id)
->where('user_id', Auth::user()->id)
->groupBy('product_id')
->get()
->count();
There is no need to use implode. you can use whereIn instead of where.
Invite::whereIn('product_id',$get_products_id)
->where('user_id', Auth::user()- >id)->get()->count();
I have three table one is orders table and another is order_status table and another is status table. Purpose of order_status table is to keep a track order's events. My table has the following column.
Order table
----------------------------
id | ref_num | name | email |
-----------------------------
Order status table has
---------------------------
order_id | status_id
---------------------
My models are like this
Order model
public function orderStatus(){
return $this->hasMany(OrderStatus::class');
}
Order status model
public function detail(){
return $this->belongsTo(Status::class,'status_id','id');
}
public function order(){
return $this->belongsTo(Order::class);
}
Now i want to get all those order which are still pending.
How can i do so ?
I tried to retrive like this but it failed
$data['orders']= Order::with(['orderStatus' =>function($q){
$q->with('detail')->latest()->where('status_id',2);
}])->latest()->take(10)->get()->toArray();
This return only one after that it does not.
Can anyone please tell me how can i sort this one ??
Thanks
PS:: one order can have multiple status such as unpaid, pending, packageging, in transit and so on but in sequence ofcouse
I added order status table image.. As u can see E7E7FF0EB7 order number has two records 1,and 2 means it was pending and then later stage got delivered.or you can say got processed. where as E02EAEA4BE has only one record of status 1. which means it is still pending.
So i want to get only those which are still pending.Not delivered.
This kinda sound complicated, hope i able to explain properly what i am trying to do.
Your model relations should be changed to a proper many to many. The schemas look correct so I'd make the following changes:
// Order model
public function statuses(){
return $this->belongsToMany(Status::class);
}
// Status model
public function orders(){
return $this->belongsToMany(Order::class);
}
This will pivot correctly on order_status.
To get pending orders the query would be:
Order::whereHas('statuses', function ($query) {
// assuming a 'name' column on statuses table
$query->where('name', 'pending');
// or using dynamic where
// $query->whereName('pending');
})->get();
Alternatively, add a scope to Order model:
public function scopePending($query) {
return $query->with(['statuses' => function ($query) {
$query->where('name', 'pending');
});
});
Usable then as: Order::pending();
Update
Try this to get all those order which are still pending..
$data['orders'] = Order::has('orderStatus', '=', 2)->whereHas('orderStatus', function ($q) {
$q->where('status_id', 2);
})->get()->toArray();
If there is two status records related to one order and one of the status value is 1 then this query will return the order record. You may update it with your exact conditions.(If you are sure that there will be only 2 status related to a order which is still pending then you may remove the second whereHas.
$data['orders'] = Order::has('orderStatus', '=', 2)->get()->toArray();
You may use the many to many relation as #DigitalDrifter suggested. I would also suggest that you should follow many to many relation.
If you are using the many to many relation then you may try the below query..
Order::has('statuses', '=', 2)->WhereHas('statuses', function ($query) {
$query->where('name', 'pending');
})->get();
or
Order::has('statuses', '=', 2)->get();
Hi im trying to query my tasks table. A little background information on the tables and how they are related.
Users, create Projects and Tasks, Statuses for projects and tasks can be selected from the status table, users make their own, i plan to have default ones but users may want to create their own.
By default i want to find all the users tasks where the status_name which is held in the statuses table does not equal closed. I decided it would be best to actually create a table called task_status which holds the task_id as well as the status_id. I still want to find the logged in users tasks and then find the status name based on the status_id held in the tasks table, which can be referenced in the statuses table. I then want to only display the any records not equal to closed but the first part which is explained below is trickier than first anticipated.
My table structures can be found below:
Table structure
Users
id | username | email
Tasks
id | user_id | client_id | project_id | status_id | task_name | task_brief
Statuses
id | status_name
Projects
id | user_id | client_id | status_id | type_id | project_name | project_brief
task_status
id | user_id | task_id | status_id
I'm trying to query my db simply first so that I can be sure that the data returned is correct. So I've changed my query to the below:
$user = User::with(array('tasks', 'task.status', 'tasks.taskstatus',
'tasks.clients'))->find(Auth::user()->id);
and I'm trying to return as follows (please bear in mind I also want to query the status table so that I am able to return the name of the status):
#foreach($user->tasks as $task)
{{ $task->task_name }}
#if(!is_null($task->clients))
{{ $task->clients->client_code }}
#endif
#if(!is_null($task->taskstatus))
{{ $task->taskstatus->status_name }}
#endif
#endforeach
My models:
Task.php
public function status(){
return $this->hasOne('Status', 'status_id');
}
public function taskstatus() {
return $this->hasMany('TaskStatus', 'status_id');
}
Status.php
public function tasks()
{
return $this->hasMany('Task');
}
public function taskstatus()
{
return $this->hasMany('TaskStatus', 'status_id');
}
TaskStatus.php
public function tasks()
{
return $this->hasMany('Task', 'task_id');
}
public function status() {
return $this->belongsTo('Status', 'status_id')
}
However using the above returns the following error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'imanage.task_statuses' doesn't exist (SQL: select * from `task_statuses`
where `task_statuses`.`status_id` in (?, ?, ?, ?, ?, ?, ?))
(Bindings: array ( 0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6, 6 => 7, ))
I'm sure that its my relationships that are defined incorrectly but I am not sure how to correct these.Can anyone help?
You can also try this code:
$user = User::whereHas('task.status', function($q)
{
$q->where('status', '!=', 'close');
})
->with('task', 'task.clients')
->where('id', Auth::user()->id)
->first();
Check the eloquent docs on querying relationships.
also remember DO NOT ECHO VIEW, return the view instead.
The error seems related to the fact that Laravel (well, actually Eloquent) is getting the wrong table name: below you have task_statuses instead of task_status. Remember that Eloquent will attempt to pluralize named models to get the table name.
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'imanage.task_statuses' doesn't exist
So either rename your table to match Laravel expectations, or in your model specify a custom table name:
class TaskStatus extends Eloquent {
protected $table = 'task_status';
...
Additionally, this part of your code is unclear to me:
Task.php
public function status(){
return $this->hasOne('Status', 'status_id');
}
public function taskstatus() {
return $this->hasMany('TaskStatus', 'status_id');
}
Does your Task have one status, or does it have many statuses?