Count two rows with scopes and relationships (Laravel) - php

So I have two tables, one called members and one called memberships
My goal is to count the number of members who have a certain membership. I've set up foreign keys and relationships are working fine, to the point where I need to do the counts.
My scope is (in Member model)
public function scopeActive($query) {
return $query->where('membership_ended_at', Null);
}
My relationship is (in Member model)
public function membership() {
return $this->belongsTo('App\Membership');
}
This query works fine, and I see how many members who are active() that has the membership_id of 6.
$members_student = Membership::find(6)->members()->active()->count();
I don't know if that's supposed to work, but it does. Now, the issue I have is that we have a regular student membership, and a student abroad membership with the ID of 14.
I assumed maybe this would work, but I quickly realized I was wrong
$members_student = Membership::find([6,14])->members()->active()->count();
I know I can call two queries and just add the two together, but I'm looking for a more elegant solution. Something that only required one query, and will half my queries.
Hopefully someone else has seen this before

Thanks to someone on laravel.io chat I managed to figure this one out. Posting it here in case anyone else is also looking for the answer.
The solution:
$members_student = Member::whereIn('membership_id', [6,14])->active()->count();

Related

Eloquent ORM - access to eager-loaded columns

I think I'm running myself in circles here, so I'm hoping to get some help - I should say that I have very little experience with PHP/laravel/eloquent, this is an inherited project.
I have a many-to-many relationship between two classes [Ticket and Comment]. I then have a many-to-one relationship between [Comment and User]. Authors on a Ticket are defined as the distinct set of users who have comments on the ticket.
I would like to eager load author IDs when retrieving tickets (I don't need the whole user, just the id)
Originally authors was given by $this->hasMany(Comments::class)->select('author_id)->distinct()
Which is fine when only retrieving them for a single ticket but will be slow when doing it for all tickets. Attempting to eager load this, even with a foreign key will fail because the ORM can't convert it to a valid SQL statement (I don't think?)
So I though I would define authors based on the comments for a ticket and eager load the comments, then theoretically I can get the distinct authors without having to go back to the database every time:
function comments()
{
return $this->hasMany(Comment::class);
}
function authors()
{
return ($this->comments == null
? $this->hasMany(Comment::class)->select('author_id')->distinct()
: $this->comments->select('author_id')->distinct());
}
I figured then that if I call:
$tickets = Tickets::with('comments')->get();
Then the authors can be determined in memory, but I think lacking a fundamental understanding of what is going on behind the scenes is causing me issues here, as this doesn't work. I suspect I'm approaching this in completely the wrong manner and would appreciate if anyone could point me in the right direction!

Laravel: Order by column value count?

I used to have a query like this
$topReferrals = User::orderBy('user_referrals', 'DESC')->get();
Recently I changed my database structure to not count user_referrals for each user in an int datatype, but to have a column for each user called referred_by and have its value who they have been referred by, I need to adapt my query to work with the new system.
I'm not quite sure how I would go about this, I was hoping someone could help?
Eloquent offers several means of counting relations. One approach would be to set the $withCount property on the User model:
// assuming your model has a referrals method.
protected $withCount = ['referrals'];
This will append an attribute on each queried model that can be used in subsequent queries or collection modifications.
User::all()->sortByDesc('referrals');
Just add referred_by column in User table as it denotes foreign key linked to the user.
Use query below to get count of users that have been referred for each referrer:
User::where('referred_by', $referred_user_id)->count();
OR
User::where('referred_by', $referred_user_id)->orderByDesc('referred_by')->get();
Note: Just make sure you have created a table for referrers to store all the details for referrers in case you want to grabs other data regarding them. You just need to add relations to the User model to directly access to the database.
public function hasReferrers () {
$this->hasOne('App\Referrer');
}
Where App\Referrer is model for your referrers table.
As I’ve understood the question, I think this is how I’d approach getting the number of referrals per user..
$all = User::all();
foreach ($all as $current) {
$current->referrals = User::where('referred_by', $current)->count();
}
$all->sortBy('referrals');
$all should now be a list of users sorted by the number of referrals.

Joining two tables Laravel

I would like to have some feedback on how to join two tables using Laravel. I have read the documentation but still I am a little bit confused. And I'm still thinking on how to handle the problem. See... I have two tables one for the kids information and the other for the vaccines, I decided to put it apart because there are a lot of vaccines and I don't want the user to input every vaccine each time they add a new kid to the system. I am planning on making some type of checkboxes for the administrator to select the vaccines each kid has, but then I have the date, so I don't know what will be the best approach.
And one of my questions is, how will I retrieve the data from the vaccines table when the user is filling out the kids information? Or do you guys have a better sugestion? I already have the table of the kids up and running, but now I have to add the vaccines.
I would glady appreaciate your help. I will also leave a picture of the two tables.
To my understanding you will need to keep another table that would manage the interaction between kids and vaccines lets say kids_vaccines.
This means that, every kid that receive one or many vaccines would have their record added with timestamp of the time the vaccine(s) was received
An example would be:
Having KidsVaccine model with relationship with Kid and Vaccine like
public function kid()
{
return $this->belongsTo(Kid::class, 'idkid');
}
public function vaccine()
{
return $this->belongsTo(Vaccine::class, 'idvaccine');
}
And both your Kid model and Vaccine model can bear a hasMany() relationship with KidsVaccine
This means that, in lets say kids_vaccines table you would be managing idkid and idvacccine as both foreign keys (ofcourse your timestamps are here, so as to know when a vaccine was applied to a kid).
This results that you can easily create a kids with vaccines retrievable from the vaccines table.
If there is anything unclear you can point it.
Hope this helps :)

Concept of table relations in Laravel

I have two tables:
Cards
Notes
Each Card has multiple Notes. So there is a relation between them like this:
class Card extends Model {
public function notes ()
{
return $this->hasMany(Note::class);
}
}
Ok well, all fine.
Now I need to understand the concept of these two lines:
$card()->$notes()->first();
and
$card()->$notes->first();
What's the difference between them? As you see in the first one $note() is a function and in the second one $note isn't a function. How will they be translated in PHP?
The first one points out to the card table and the second one points out to the notes table, right? or what? Anyway I've stuck to understand the concept of tham.
I don't know about $ before the $notes in your code but if you trying to say something like this.
1- $card->notes()->first();
2- $card->notes->first();
In the code in line 1, first you have a $card model and then you wanted to access all notes() related to that $card, and because of adding () after notes you simply call query builder on notes, show you can perform any other database query function after that, something like where, orderBy, groupBy, ... and any other complicated query on database.
But in the second one you actually get access to a collection of notes related to that $card, we can say that you get all related notes from database and set it into laravel collections and you are no more able to perform database query on notes.
Note: because laravel collections have some methods like where(), groupBy(), whereIn(), sort(), ... you can use them on the second one, but in that case you perform those methods on collections and not database, you already get all results from database

laravel one to many(select all rows from second table)

i want to select all services rows from servs table
_____ i have two tables users with model(User) ..... and servs with model(servs) ... . uwant to select all rows from servs when it auth User
How can i do that ???
public function postserv(){
$serv = User::find(Auth::user()->id)->servs;
$serv = $serv->first();
return $serv->serv_id;
}
I'm not sure of the model name, but it should be something like Serv::all()
Your question is very vague and it's hard to determine what's going on in your project but I'll give it a shot.
If you want to select all rows of a model use the following:
Services::all()
Whilst that is what you're explicitly asking for, your question seems to pertain to a relationship where you select all services for a user.
User::find(Auth::user()->id)->servs()->get();
This will return all services that are joined to the authorised user, on the note of naming conventions you should make your relations more readable.
Also note that you must have your relationships set up in your Eloquent models else the above code would fail.
In future try to add a little more detail for your questions, there is more information about relationships in the Eloquent ORM on the Laravel website.
ModelName::all();
Returns all rows from a model/table.

Categories