I have users table, user_roles table and roles table.
My user_roles table:
id, role_id, user_id
My roles table:
id, name, description, created_at, updated_at
My users table:
id, first_name, last_name, user_name, avatar, account_status, email, password, remember_token, created_at, updated_at, deleted_at
Now I am trying to get the logged in user with the role including the role description, but cannot seem to get it working.
In my user model I have this:
public function roles()
{
return $this->hasOne(User_roles::class, 'role_id', 'id');
}
This gives me the User_role but no description. I tried belongsToMany, but this gave me the Roles values and pivot with the User_roles table valus. Can I do it vice versa so I get the User_roles table values and pivot will be the description of the Roles table?
BelongsToMany relationship at the moment:
public function roles()
{
return $this->belongsToMany(Roles::class, 'user_roles', 'id', 'id');
}
Use hasManyThrough relation instead:
https://laravel.com/docs/5.6/eloquent-relationships#has-many-through
This way you can specify the intermediate user_role table
You should try to below solution
In User Model
public function roles()
{
return $this->belongsToMany(Role::class, 'user_roles');
}
In Controller
$user = User::find($user_id);
$roles = $user->roles;
In User Model
public function roles()
{
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
}
Related
I have a relationship between two models, User and Follower.
User hasMany Follower, and Follower belongsTo User.
In my followers table in the database I have two columns, follower_id and following_id. Both these columns refer to the id column in the users table.
My follower and users table
followers
id
follower_id
following_id
users
id
name
username
User Model
public function followers(){
return $this->hasMany('App\Follower', 'follower_id');
}
public function followings(){
return $this->hasMany('App\Follower', 'following_id');
}
Follower Model
public function user(){
return $this->belongsTo('App\User');
}
In a test controller I am doing this:
$followed = Follower::find(2);
From here, I would like to select one of the columns, follower_id or following_id, and access the user that this particular row belongs to by using $followed->user->name. How would I go about that? Since I need to select a column before accessing, I am a little bit confused.
What can I do to access the data I need?
Your table should be :
followers
id
follower_id
following_id
user_id
users
id
name
username
In your Follower model :
public function user()
{
return $this->hasMany(Follower::class, 'user_id');
}
In your User model :
public function follower()
{
return $this->belongsTo(User::class, 'user_id');
}
Then you can query like this :
$follower = Follower::with('user')->findorFail(2);
$user_name = $follower->user->name;
I am trying to delete hasMany relationship but to no avail.
I have three tables: users, user_details, and manufacturers
User hasOne user_details
user_details belongsTo user
manufacturers have many users through user_details
Now when admin deletes manufacturer, it needs to delete all user_details who has that manufacturer_id and all related users.
My tables:
Users:
id, unique_id, first_name, last_name, user_name, email, password, remember_token, created_at, updated_at, deleted_at
User_details
id, user_id, avatar, locale, role_id, manufacturer_id, account_status, hospital_id, phone, city_id, created_at, updated_at, deleted_at
Manufacturers
id, name, status, created_at, updated_at, deleted_at
I am trying to do it like this:
/**
* #return bool|null
* #throws \Exception
*/
public function softDelete()
{
$this->brand_presentations()->delete();
$this->details()->delete();
return parent::delete();
}
And here I have my relations:
public function brand_presentations()
{
return $this->hasMany(Brand_presentations::class, 'manufacturer_id', 'id')->withTrashed();
}
public function details()
{
return $this->hasMany(User_details::class, 'manufacturer_id')->withTrashed();
}
This gives me all the way to the user_details, but I cannot get users. How can I get the users?
If I am understanding you correctly you need to loop through your details to be able to delete the user
/**
* #return bool|null
* #throws \Exception
*/
public function softDelete()
{
$this->brand_presentations()->delete();
$details = $this->details
foreach($details as $detail) {
$user = detail->user
// Delete or access user here
$detail->delete()
}
}
So im trying to figure out how to use pivot tables in Laravel. And I have tried to read and understand the documentation. And I cannot understand why a user just can't balongTo a "department". I don't want a user to belongToMany "departments".
Departments model
public function users()
{
return $this->belongsToMany(User::class, 'department_user', 'user_id', 'department_id');
}
And for the user model, I want something like
public function department()
{
return $this->belongsTo(Department::class);
}
But Laravel reports null. Because department_id doesn't exist in the users row? How can I reverse this pivot table lookup, with belongsToMany and belongsTo?
I think you're getting confused with your relationship types. If I understand you correctly:
A Department hasMany Users.
A User belongsTo a Department.
This one-to-many relationship type does not need a pivot table and can be written as such:
class Department extend Eloquent
{
public function users()
{
return $this->hasMany(User::class);
}
}
class User extend Eloquent
{
public function department()
{
return $this->belongsTo(Department::class);
}
}
This would require that the users table have a department_id foreign key.
I have the following Models with corresponding tables:
User (users), UserProfile (user_profiles), Review (reviews)
Schema
table: users
user_id (primary key)
first_name
last_name
table: user_profiles
user_id (foreign key)
country
phone
table: reviews
reviewer_id (the user who posted the review)
user_id (foreign key)
body
I query the database with the following:
$user = User::with('profile', 'review')->find(Auth::User()->user_id);
Part of User Model
public function profile(){
return $this->hasOne(UserProfile::class, 'user_id');
}
public function review(){
return $this->hasOne(Review::class, 'user_id');
}
Part of UserProfile Model
public function users() {
return $this->belongsTo(User::class, 'user_id');
}
Part of Review Model
public function users() {
return $this->belongsTo(User::class, 'user_id');
}
How can I access the details of the reviewer using the reviewer_id from the users table
As a sunup of what was discussed in this question, I think the major concern of OP was regarding a table that have 2 foreign keys with the same table. Both user_id and reviewer_id are foreign keys linked to the users table.
One important thing to understand about Laravel relationships is that the relationship name is not hard bound, it can be anything as long as it makes sense to you. The related object will be available in the ATTRIBUTE with the exact name of the METHOD.
class User extends Model {
public function review() {
return $this->hasOne(Review::class);
}
}
A user's review will be available at User::find(1)->review;.
class Review extends Model {
public function owner() {
return $this->belongsTo(User::class, 'user_id');
}
public function reviewer() {
return $this->belongsTo(User::class, 'reviewer_id');
}
}
From a review, you will be able to access both users:
Review::find(1)->owner; // This is the relationship with user_id column
Review::find(1)->reviewer; // This is the relationship with reviewer_id column
So I have User & Role models with many-to-many relationship, I have 3 roles: super, admin and moderator with 4 users let's says: John, Mike, James and Larry.
John is a super, Mike has admin and moderator roles, James is an admin and Larry is a moderator. To displaying users who doesn't have certain roles I created this scope:
public function scopeDoesntHaveRoles($query, $roles = [], $column = 'id') {
return $query->whereDoesntHave('roles')->orWhereHas('roles', function ($q) use ($roles, $column) {
$q->whereNotIn($column, $roles);
});
}
When I call User::doesntHaveRoles([1])->lists('name', 'id') to get users who doesn't have super role, it works and returns:
{"2":"Mike","3":"James","4":"Larry"}
But, when I trying to list users who doesn't have admin role User::doesntHaveRoles([2])->lists('name', 'id'), yes James is not shown there but Mike is appeared while he is actually has admin role:
{"1":"John","2":"Mike","4":"Larry"}
I think it's because Mike is also has moderator role, do you see something wrong in my scope? or do you have other solutions?
Thanks
Edit:
Here is my pivot schema
Schema::create('user_roles', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->primary([
'user_id', 'role_id'
]);
});
User model
public function roles()
{
return $this->belongsToMany(Role::class, 'user_roles');
}
Role Model
public function users()
{
return $this->belongsToMany(User::class, 'user_roles');
}
I would use whereNotIn instead of whereDoesntHave.
Given a Role stored in the variable $role you can get all users who don't have that role with:
/* #var Role $role */
User::whereNotIn(function('id', $query) use ($role) {
$query->select('user_id')
->from('user_roles')
->where('role_id', $role->id);
});
The inner query will return all IDs of users who has the given role. Using whereNotIn will return the opposite set of users. The folowing query will be created:
select *
from users
where user_id not in (
select user_id
from user_roles
where role_id = ?
);
Now having a Collection of roles stored in $roles you can get all users who don't have any of that roles with:
/* #var Collection|Role[] $roles */
User::whereNotIn(function('id', $query) use ($roles) {
$query->select('user_id')
->from('user_roles')
->whereIn('role_id', $roles->pluck('id');
});
The inner select will return IDs of all users who has one of the roles in the collection. With whereNotIn you will again get the opposite result. You can also use an array of role-ids instead of $roles->pluck('id').
The builder will create a query like
select *
from users
where user_id not in (
select user_id
from user_roles
where role_id in (?, ?, ..)
);