Laravel: how to sort a collection with hasMany field - laravel

I have five tables:
details having fields id, name and has hasMany relation with contributions.
purpose having fields id, name and has hasMany relation with contributions.
period having fields id, name and has hasMany relation with contributions.
user having fields id, name and has hasMany relation with contributions.
and
contributions having id, amount and "belongsTo" relation with user_id, detail_id, purpose_id, period_id
Now, I want to get all contributions of a specific user (filtered by user_id) and then sort the result by period.name, detail.name and purpose.name.
Any suggestions?
The question has been identified as possible duplicate of Laravel orderBy on a relationship . However there is a basic difference.
there, there is relation between user and comment & user and post. however in my case, there isn't any relation between user and details/purposes/periods tables.
<?php
class User
{
public function comments()
{
return $this->hasMany('Comment');
}
}
is possible in that case, but by same analogy, in my case, class User doesn't have any details() function to get hasMany relations. My user has relation with only contributions table and contributions table has relations with details purpose etc tables.
hope I am able to clarify the difference.

Related

Laravel 9.* belongsToMany

I have DB structure:
user
user_id
office
office_id
property
property_id
office_user
office_user_id
office_id
user_id
office_user_property
office_user_id
property_id
Is there way to acess to Property model from User model via belongsToMany?
What you are looking for is the hasManyThrough
(https://laravel.com/docs/9.x/eloquent-relationships#has-many-through), but it only work for one connection in between, and you have two.
What you could do is define a hasManyThrough relation between user and office_user_property and define a hasOne relation between office_user_property and property
belongsToMany refers to Many To Many. This relationship for your case defines that has many properties, while a property is owened by many users. In a nutshell three database tables can be used to define this relationship. properties table, users table, and user_property table. where the user_property table contains user_id and property_id columns.
In the user model, the relationship can be defined as:
/.../
public funciton properties(){
return $this->belonsToMany('App\Property');
}
To access properties for a user:
$user = App\User::find(1);
foreach ($user->properties as $property) {
//
}
Ref: Laravel 5.2 Docs

Invalid argument supplied for foreach() in laravel when use Eloquent: Relationships

I wanna get the class name of a user via the user ID. When I input the ID of a user so I will wanna get the class name. I have three tables such as users table, classes table, and class_users table. The class_users table is born from two users table and classes table.
A users table has an id, name, email, password.
A classes table has an id, class_code, class_name.
A class_users table has an id, class_id, user_id
And this problem relates to Eloquent Relationships.
Thank you for help.
My Route:
Route::get('/find_classes/{id}','StudentController#find_classes');
My Controller function:
public function find_classes($id)
{
$users = User::find($id);
foreach($users->classes as $class)
{
echo $class->name . '<br';
dd($class);
}
}
My User Model:
public function classes()
{
return $this->belongsTo('App\Classes','class_users','user_id','class_id');
}
Looks like you might have the wrong relationship set up on your User model. You have a one to many set up, but your DB is setup to handle a many to many. I suggest you change your User model relationship:
public function classes()
{
return $this->belongsToMany('App\Classes');
}
Note, you may need to name the FK on that relation, as I see you have class_id on the table, but your actual class is named 'Classes'. Check through your relationships to ensure this is explicit on the FK where it doesn't follow Laravel convention exactly.
With this relationship, your foreach loop should work. It would be a good idea for efficiency, as mare96 noted, to eager load the classes on the $users collection when you query:
$users = User::with('classes')->find($id);

Have 2 one to one relationships between the same models

I have a User model & a Sale model. A User can be either a Merchant or Customer.
When a sale is made the sale belongs to a merchant but also to a customer.
I figured I can give the sale a merchant_id & a sale_id and create 2 different relationships in the models.
Just didn't feel right to me. So my question is there a better way to go about this? I'm in a early stage of development. I wouldn't mind changing the database around a bit.
I'm using laravel 5.3
It's not one-to-one, it's many-to-many relationship and sales table should be a pivot table. Relation usually looks like this:
class User extends Authenticatable
{
public function customers()
{
return $this->belongsToMany('App\User', 'sales', 'customer_id', 'merchant_id');
}
Where customer_id and merchant_id are foreign keys pointed to id in users table.
If you do a lot of stuff with sales table, just keep using Sale model for this pivot table.

laravel one-to-many get data without inner join

I am trying to get a feel around the laravel ORM and I have the following models.
I have a:
user table with- id, firstname, lastname
city table with - id, name
usercity table with - user_id, city_id
The usercity table tracks the cities the user has visited.
I added the following in city model:
public function usercity()
{
return $this->hasMany('App\UserCity');
}
And another function in user model
public function usercity()
{
return $this->hasMany('App\UserCity');
}
I also added a model for UserCity and added following function there.
public function city()
{
return $this->belongsTo('App\City');
}
public function user()
{
return $this->belongsTo('App\User');
}
Now, the goal is to retrieve all the cities a user has visited. I used the following function.
$usercities = User::where('id','=',1)->first()->usercity()->get();
This works in the sense that it retrieves the user_id and city_id.
What would i need to do to get all the fields in the city table also?
Current response:
[[{"user_id":"1","city_id":"1"},{"user_id":"1","city_id":"2"},{"user_id":"1","city_id":"3"},{"user_id":"1","city_id":"4"}]]
I might be able to use inner join but I wanted to see if there was another way to retrieve the data which safely populates the data for me.
What you really have is a many-to-many relationship between users and cities, with the usercity table being the pivot table. Laravel uses the BelongsToMany relationship to implement this. You'll need to make a few changes to get this to work.
In your city model:
public function users() {
return $this->belongsToMany('App\User', 'usercity');
}
In your user model:
public function cities() {
return $this->belongsToMany('App\City', 'usercity');
}
You can get rid of the UserCity model. There is usually no reason to need a model for the pivot table.
The usercity table may need to be updated to add an id field as the primary key. I've not tried it without one, however, so it may work as you have it. Also, if you wanted, you could rename the table to city_user to conform to Laravel conventions, and then you wouldn't need to specify the table name in the relationship definitions.
Once your relationships are setup correctly, you can access a user's cities via the cities relationship on the user, and you can access a city's users via the users relationship on the city. For example:
// all of the cities visited by user 1
$user = User::find(1);
$usercities = $user->cities;
// all of the users that have visited city 1
$city = City::find(1);
$cityusers = $city->users;
You can find more information about the relationships in the documentation here.

Laravel and pivot table to relate different model

I'm wondering how, but it's bit confusing.
I have fine belongs to many relation between users and groups tables as well as appropriate models for all of that.
But i also have table students, where not all users are student so i students table i maintain user_id field.
My question would be: Can i use pivot table "group_user" for relations between student and group model, in students table i have "user_id" field? and how?
I tried something like
public function students()
{
return $this->belongsToMany('Student','group_user','group_id','user_id');
{
but i don't see the way how to tell eloquent not to take students.id but to take students.user_id???
Assuming these relations:
Subject belongsTo Group
Group belongsToMany User
User hasOne Student
you can easily do this:
$subject = Subject::find($someId);
// of course for multiple subject use eager loading:
// $subjects = Subject::with('group.users.student')->get();
$users = $subject->group->users; // related users
foreach ($users as $user)
{
$user->student; // null|student model
}

Resources