This error has been posted here several times but I'm encountering something a little different. I have two Tables named users and user_type. And users uses a foreign key from user_type. I have to fetch all users and their types, I'm using Laravel's Eloquent ORM to define relationships, this is a one to one relation.
Users Model:
/**
* Get the user type that user has.
*/
public function users(){
return $this->belongsTo('App\Models\UserType', 'ut_id', 'id');
}
UserType Model:
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'ut_id';
/**
* Get the user associated with the user type.
*/
public function users(){
return $this->hasOne('App\Models\Users', 'user_type_id', $this->primaryKey);
}
Fetching Controller:
$users = Users::all()->users;
According to Laravel ORM one-to-one I can access this method as a property, but it's showing me the defined error. I've also tried to access it as a method but it's saying:
Method Illuminate\Database\Eloquent\Collection::users does not exist.
I've also tried to fetch them by join() but it's returning only a few users, I don't know why:
$users = Users::where('id', '>', '0')
->join('user_type', 'user_type.ut_id', '=', 'users.id')
->select([
'user_type.ut_name',
'users.*'
])->get();
Can someone tell me what I'm doing wrong?
P.s: I just want to show all the users with their respective types
You had missed the exact foreign key between your users table and usertypes table.
First, you defined the that the foreign key of your user table is 'ut_id' base of what you had in your belongsTo relationship. On this one
/**
* Get the user type that user has.
*/
public function users(){
return $this->belongsTo('App\Models\UserType', 'ut_id', 'id');
}
Second is that, in your user type model, you used a foreign key to user table named 'user_type_id', which is at first you named it as 'ut_id' in your users table. On this one
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'ut_id';
/**
* Get the user associated with the user type.
*/
public function users(){
return $this->hasOne('App\Models\Users', 'user_type_id', $primaryKey);
}
You have to match this foreign keys you used to solve your problem.
Now, to fetch your all user with their types, your query should look like this.
$users = Users::with('users')->get();
assuming that your user table has this relationship
public function users(){
return $this->belongsTo('App\Models\UserType', 'ut_id', 'id');
}
and your user types model has this relationshio
public function users(){
return $this->hasOne('App\Models\Users', 'ut_id', $this->primaryKey);
}
in User model
public function type(){
return $this->hasOne(UserType::class, 'id');
}
in UserType Model
public function users(){
return $this->belongsToMany(User::class, 'id');
}
Your relations seem to be wrong.
Users links to UserType with id to ut_id, but userType links to User with id to user_type_id
I'm pretty sure that it should be this for userTypes
/**
* Get the user associated with the user type.
*/
public function users(){
return $this->hasMany('App\Models\Users', 'id', 'user_type_id');
}
and then this for Users
public function userTypes(){
return $this->belongsTo('App\Models\UserType', 'user_type_id', 'id');
}
Then you can eager load for all the results you want...
$users = Users::where('id', '>', '0')
->with('userTypes')
->get();
Related
I have two models:
Order
Customer
I have customer_id in orders table. Customer details (name, phone, email etc) in customerstable. But I am writing query for orders table.
Now, I want to search with Customer Name on Orders but in Orders table I just have customer_id.
How will I link up with customers table so that I can search with Customer Name. I want to do that with Eloquent.
How is this possible?
There are multiple ways of doing relationship filtering with Eloquent.
You can achieve it with whereHas or using an advanced join / left join query.
I suggest you do a research about Eloquent filtering on Laravel documentation, everything you need for your task should be there.
https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence
https://laravel.com/docs/8.x/queries#advanced-join-clauses
In models define relationships
Customer model
public function orders()
{
return $this->hasMany(Orders::class);
}
Order model
public function customer()
{
return $this->belongsTo(ustomer::class, 'foreign Key', 'id');
}
Then you can call relationships and search what you want
Customer::whereHas('orders')
First you need to create relationship in the orders model, you can use either belongsTo or hasOne relationship.
belongsTo relationship will be like as below
public function customer()
{
return $this->belongsTo(ustomer::class, 'foreign Key', 'id');
}
and the hasOne relationship will be like as below
public function customer()
{
return $this->hasOne(Customer::class, 'foreign_key', 'local_key');
}
The search function will be like as below
public function OrderSearch(Request $request){
try {
/**
* Fetching data with orders relationship
*/
$orders = OrdersModel::with(['customer'])
if(!empty($request->search)){
/**
* Searching the name key inside
* the customer relationship
*/
$orders->where(fn($query)=>
$query->whereHas('customer',fn($query2) =>
$query2->where('name','LIKE','%'.$request->search.'%'));
);
}
/**
* Returning the response
*/
return $orders->get();
} catch (\Throwable $th) {
throw $th;
}
}
Kindly refer the laravel eloquent-relationships documentation : eloquent-relationships
I have a model called unit that has this relationship
/**
* Get the users associated with the unit
*/
public function users()
{
return $this->hasMany('App\Models\User\UserData');
}
In the UserData model there is a column called user_id which I am trying to put in my condition in my query. I am trying to do a query like this
Unit::where('user_id', Auth::id())->first()
but there is no user_id column in the Unit table, only though the users relationship
Ended up doing this
Unit::whereHas('users', function($q) {
$q->where('user_id', Auth::id());
})->first();
I'm stuck with a problem where I have to sort / order a collection of models by their relationship's data.
I've got it setup like this:
Models:
User, Team, TeamUser, Role
The TeamUser model is a pivot model / table (containing user_id and team_id.
If it's worth mentioning I am also using spatie/laravel-permissions for the roles.
How would I go forth when I want to sort the users in a team by their role.name?
I'm talking about the users() relation in the Team model (see further down for code sample).
Some users have the role team-leader and most have the role team-seller. I've tried doing a ordinary ..->sortBy('role.name') but that doesn't seem to work. Thanks in advance if anyone could help me out.
User.php
/**
* Team relation
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function team()
{
return $this->belongsToMany('App\Team', 'team_users', 'user_id', 'team_id');
}
Team.php
/**
* User relation
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users()
{
return $this->belongsToMany('App\User', 'team_users', 'team_id', 'user_id')->withTimestamps();
}
if you want to order the result based on nested relation column, you must use a chain of joins:
$values = Team::query()
->leftJoin('users', 'users.team_id', '=', 'teams.id')
->leftJoin('model_has_roles', function ($join) {
$join->on('model_has_roles.model_id', '=', 'users.id')
->where('model_has_roles.model_type', '=', 'app\Models\User');
})
->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
->orderBy('roles.name')
->get();
i have tried it, it work just fine.
please note that if you want to order by multiple columns you could add 'orderBy' clause as much as you want:
->orderBy('roles.name', 'DESC')->orderby('teams.name', 'ASC') //... ext
i've a question about Laravel Relationships.
I've a raw union query and i want to translate into a eloquent relationship.
First of all... i have 4 tables involved:
roles
id|name
permissions
id|name|code|description
permission_role
role_id|permission_id
users
id|...........|role_id
permission_user
user_id|permission_id
Inside my User model, i've this method:
/**
* #TODO: Transform this into a eloquent relationship
*
* #return Collection
*/
public function permissions()
{
$query = sprintf('
(
SELECT permissions.*
FROM permissions
INNER JOIN permission_role ON permission_role.permission_id = permissions.id
WHERE permission_role.role_id = %s
) UNION
(
SELECT permissions.*
FROM permissions
INNER JOIN permission_user ON permission_user.permission_id = permissions.id
WHERE permission_user.user_id = %s
)', $this->role_id, $this->id);
return Permission::hydrate(DB::select($query));
}
The point is, i want to fetch all permissions by the role that the user is associated, and the separated permissions associated to the user.
Can i transform this in some eloquent relationship like hasMany, belongsToMany, etc... ?
The "merge" function in Laravel collection might be able to help you.
The big differnt is that I close off the query with ->get() in advance, and I use merge() instead of union()
// In Controller
public function GetUsersWithPermission()
{
$permissionByRole = User::with('permission_role.permission')->get();
$permissionByUser = User::with('permission_user.permission')->get();
$result = $permissionByRole->merge($permissionByUser);
}
// User Model : get PermissionRole By User
public function permission_role() {
return $this->hasOne('App/Model/permission_role', 'role_id', 'role_id'); }
public function permission_user() {
return $this->hasOne('App/Model/permission_user', 'user_id', 'id'); }
// permission_role Model : get Permissions By Role
public function permission(){
return $this->hasMany('App/Model/Permissions', 'id', 'permission_id'); }
// permission_user Model : get Permissions By User
public function permission(){
return $this->hasMany('App/Model/Permissions', 'id', 'permission_id'); }
Note: I don't have your data so I can't proof it work, but it least it work on my data so should worth your try. and it return all data like: all user details, and permissions so you can use select() function to get Specific Columns.
I've got a strange problem.
I've a users table and a company table. A User belongsTo a company and a company hasMany users.
Both primary keys of the table are id.
In the laravel documentation I read the following:
Additionally, Eloquent assumes that the foreign key should have a
value matching the id column of the parent.
I've got this in my CompanyModel:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class);
}
When I try this:
$users = CompanyModel::find(1)->users;
dd($users);
It's not working. When I add a foreign key in my relation it works!?:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class, 'id');
}
This is strange right? What on earth am I doing wrong.
--EDIT--
In my users table I've got a company_id column!
Firstly, I would suggest you rename your Model from CompanyModelto Company and from UserModel to User.
Then ensure you have company_id in your users table. And in your users migration file connect the users table with the companies table as such:
$table->integer('company_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
Don't forget to refresh your database.
Then in your models, define the relationships as such:
// User model
// Laravel will automatically identify and use the `company_id` field in your reference
public function company(){
return $this->belongsTo(Company::class);
}
// Company model
public function users(){
return $this->hasMany(User::class);
}
You can then fetch your records in your controller as such:
$user = User::find(1);
$user_company = $user->company; // This might not be necessary in your controller, you can do it in your view
dd($users, $user_company);