view database data that was created today by a specific user - laravel

I'm creating a foodlog and I want a user to be able to search through the days and view food that was only logged that day.
For example, on the page for today's date I only want to see all the food items that I logged for today.
I have my table getting all data from that specific user from all dates, but how do I narrow it down to just today?
FoodlogController.php
public function show() {
$userId = Auth::user()->id;
$posts = Post::where('user_id', $userId)->get();
return view('foodlog', compact('posts'));
}
This is what my table looks like

I'm going to assume you have the default timestamps on, which add created_at and updated_at fields. If that's not the case, and you log time of creation with a different column, just replace the created_at with it.
Laravel comes with a hand package for dealing with dates - Carbon, which can be used by importing it from Carbon\Carbon namespace.
And Laravel's query builder has a method whereDate (scroll to "whereDate"), which can be used exactly for this.
Combining these 2, you could do this:
$posts = Post::where('user_id', $userId)->whereDate('created_at', \Carbon\Carbon::today())->get();
This will get the posts that were created today.
However
I would strongly recommend you create a hasMany relationship (user hasMany posts and inversely a post belongsTo a user), which would enable to use relationships and do something like this:
$posts = $user->posts()->whereDate('created_at', \Carbon\Carbon::today())->get();
And many more things, the Laravel way.

Related

how to retrieve users based on the selected categories and sub categories from database in laravel

I would like to begin with the messy things I have done with the database architecture.
I have put the fields title, description, donation_amount, in the users table which should have been in a different table. But now if I change this, I would have to change a lot of things.
The ManyToMany relation is already setup between these tables in laravel. I tried to join tables that query builder as well.
There are different roles in the application. We will talk specifically about Donor When a Donor registers in the Application. It selects multiple categories and sub_categories which stores in selections table.
Now when a donor logs in to the application. It should only get the records based on the categories selected.
Now I am confused how can I retrieve the users based on the logged in users selected categories and sub_categories.
I have tried joining the tables which works well but it is getting all the results against the joined tables.
DB::table("users")->select('users.*')->from('categories')
->join('selections','categories.id', '=', 'selections.category_id')
->join('users', 'users.id','=', 'selections.user_id')
->join('sub_categories','sub_categories.id', '=', 'selections.sub_category_id')
->where('users.status','approved')->paginate(6);
Relations in the model Category
public function users() {
return $this->belongsToMany(User::class,'selections');
}
Relations in the model User
public function categories() {
return $this->belongsToMany(Category::class,'selections');
}
If there is a way of doing this calling eloquent relationships. I would love the help else It would be evenly nicer to get the job done with the joins I have already implemented.
Use has-many-through relationship.
https://laravel.com/docs/9.x/eloquent-relationships#has-many-through
In other way you can query like this :
DB::table("users")->select('users.*')
->whereIn('users.id',function($query) use ($specific_category_id){
$query->select(''user_id')->from('selections')->where('category_id',$specific_category_id)
})
->where('users.status','approved')->paginate(6);

Laravel: Pull data from multiple tables

I am new to Laravel but I dont think Im writing optimised code. I am looking at getting all overdue invoices separated by clients. Invoices table and clients table. client_id is within the invoices table. I have the following below but I wanted to know if there is a better way. I would also want to grab the client name from the clients table. I have created an array so I can loop throgh accordingly on the view file, but again im not sure this is the correct way?:
$overdueClients = Invoice::where("date_paid",'0000-00-00')->where("date_due","<=",date("Y-m-d"))->pluck('client_id');
foreach($overdueClients as $overdueClient)
{
$invoices = Invoice::select("title","total","on_account","date","date_due")->where("date_paid",'0000-00-00')->where("date_due","<=",date("Y-m-d"))->where('client_id',$overdueClient)->get();
$return[$overdueClient][] = $invoices;
}
return $return;
yes luckily there is a better way for which term is called relations and can use eager loading so what you can do is to make relation is models first :
so in you Invoice model you write something like below :
public function users(){
return $this->belongsTo('App/Users');
}
you should fix the above relation according to the name and path of your model and in your users model :
public function invoices(){
return $this->hasmany('App/Invoices');
}
so now an invoice belongs to a user and a user can Have many Invoices . and when you need to get the users which has invoices and overdue invoices you do like below :
$users = Invoices::with('users')->where("date_paid",'0000-00-00')->where("date_due","<=",date("Y-m-d"));
this is the better way to act because of preventing n+1 problems this way you only load users if they have overdue invoices if not they are not being loaded at all take a look at documentation below :
https://laravel.com/docs/7.x/eloquent-relationships#introduction
i strongly recommand to take time and read this and practice it as you would need it more that you think when you want to work with laravel . hope this helps

Wrong ID returned from local Eloquent scope

In my Laravel project I've got a model (and an underlying table) for lessons. Now I'm trying to write a local scope for returning all lessons that have been finished by a particular user. The definition of "finished" is that there exists a row in a table named "lesson_results" with this lesson's ID and the users ID.
My scope currently looks like this:
public function scopeFinished($query, User $user)
{
return $query->join('lesson_results', function($join) use($user)
{
$join->on('lesson_results.lesson_id', '=', 'lessons.id')
->where("user_id", $user->id);
});
}
This kinda works. When I do a Lesson::finished($user)->get() I get out the correct lessons for that user. However the lessons in the collection returned all have the wrong ID's! The ID's I see are the ID's from the lesson_results table. So when I check $lesson->id from one of the returned items I don't get the ID from that lesson, but the ID from the corresponding row in the lesson_results table.
I've checked in mysql and the full query sent from Laravel is the following
select * from `lessons` inner join `lesson_results` on `lesson_results`.`lesson_id` = `lessons`.`id` and `user_id` = 53
This query DO return two columns named id (the one from the lessons table and the one from the lesson_results table) and it seems Laravel is using the wrong one for the result returned.
I don't know if I'm going about this the wrong way or if it's a bug somewhere?
This is on Laravel 7.6.1.
edit: Ok, I think I actually solved it now. Not really sure though if it's a real solution or just a workaround. I added a select() call so the return row now is
return $query->select('lessons.*')->join('lesson_results', function($join) use($user)
...which makes it only return the stuff from the lessons table. But should that really be needed?
One of the same column names will be covered by the other.
Solution 1:
Specify the table with the column, and alias the other table's column if it has same column name.
Lesson::finished($user)->select('lessons.*', 'lesson_results.id AS lesson_result_id', 'lesson_results.column1', 'lesson_results.column2',...)->get();
Solution 2:
Or you can use Eloquent-Builder eager-loading whereHas,(Assuming you have build the relationship between model Lesson and model LessonResult)
public function scopeFinished($query, User $user)
{
return $query->whereHas('lessonResults', function($query) use($user)
{
$query->where("user_id", $user->id);
});
}
So you can get lesson like this:
Lesson::finished($user)->get();

Laravel complicated relationship

My laravel app structed like this:
People: Model & Controller
Pets: Model & Controller. Has many to many relationship with People.
Abiilities: Model & Controller.
People_pets: People pets. (pivot table with people_id and pet_id). Also has 4 columns of abbility1_id, abbility2_id, abbility3_id and abbility4_id.
Now.. I built an API method to return the user pets, and it looks like this:
public function pets()
{
return $this->belongsToMany(Pet::Class, 'user_pets')->withPivot(
'abbility1_id',
'abbility2_id',
'abbility3_id',
'abbility4_id'
)->orderBy('position','asc');
}
which makes $user->pets returns the user list of pets, with the pivot information of user_pets and the abbility ids.
The question
What I want to do is add a json object to this method result named "abbilities" and get the data of the abbilities there such as name and description from the Abbilities model/controller.
How I can add the abbilities information to my query out of just the ID's?
The output of the current API CALL:
Desired output: array of Abbilities inside every pet object with the detail of the attack_id's inside $user->pets->pivot->attack1_id
You could just use the query builder and orWhere to grab the data. I don't think you can access it through relationships with the way you have it set up.
I don't know how you access your pet ability ids, but I'm guessing it's like $pet->abbility1_id.
$abbilities = Abbilities::where('id', '=', $pet->abbility1_id)
->orWhere('id', '=', $pet->abbility2_id)
->orWhere('id', '=', $pet->abbility3_id)
->orWhere('id', '=', $pet->abbility4_id)
->get();

eloquent filter result based on foreign table attribute

I'm using laravel and eloquent.
Actually I have problems filtering results from a table based on conditions on another table's attributes.
I have 3 tables:
venue
city
here are the relationships:
a city has many locations and a location belongs to a city.
a location belongs to a venue and a venue has one location.
I have a city_id attribute on locations table, which you may figured out from relationships.
The question is simple:
how can I get those venues which belong to a specific city?
the eloquent query I expect looks like this:
$venues=Venue::with('location')->where('location.city_id',$city->getKey());
Of course that's not gonna work, but seems like this is common task and there would be an eloquent command for it.
Thanks!
A couple of options:
$venues = Venue::whereIn('location_id', Location::whereCityId($city->id)->get->lists('id'))
->get();
Or possibly using whereHas:
$venues = Venue::whereHas('location', function($query) use ($city) {
$query->whereCityId($city->id);
})->get();
It is important to remember that each eloquent query returns a collection, and hence you can use "collection methods" on the result. So as said in other answers, you need a Eager Loading which you ask for the attribute you want to sort on from another table based on your relationship and then on the result, which is a collection, you either use "sortBy" or "sortByDesc" methods.
You can look at an example below:
class Post extends Model {
// imagine timpestamp table: id, publish, delete,
// timestampable_id, timestampble_type
public function timestamp()
{
return $this->morphOne(Timestamp::class, 'timestampable');
}
}
and then in the view side of the stuff:
$posts = App\Post::with('timestamp')->get(); // we make Eager Loading
$posts = $posts->sortByDesc('timestamp.publish');
return view('blog.index', compact('posts'));

Resources