Polymorphic relations in Laravel - laravel

Please, Help me!
I have User model and migration: id, login, password.
3 roles and models (Admin, Teacher, Student) and here more information about user. And user can get several roles (he can be admin and teacher)
And one polymorphic model Role with columns:
user_id
roleable_id
roleable_type
For example, User::find(1)->roles;
And i'd like that result shows two model (admin and teacher).
Pleasee, help me))

You could try to eager load the models by using this in your User model https://gist.github.com/thisdotvoid/3022fee8afa53e45a6b89da3f16b3815. Add the required morph functions and then add three functions to the user model similar to this one (change the name and the model name accordingly):
public function admin()
{
return BelongsToMorph::build($this, 'App\Admin', 'rolable');
}
Then create a mutator function like
function getRolesAttribute()
{
$roles = new Collection();
$roleNames = ['admin', 'teacher', 'student'];
foreach ($roleNames as $role) {
$hasRole = $this->{$role};
if ($hasRole) {
$roles->push($role);
}
}
return $roles;
}

Related

How get users from section table ? laravel

The idea is that I have relation between two table's section and user
the section_id exist in users table it relation with id section
SO for ex : section_id = 2 > want to bring all users belongs to id section
My code here use id from url and I don't want to do this I want without id bring all users :
public function getAllUsers($id)
{
$data = User::where('section_id',$id)->get();
}
If I'm understanding you correctly, you want to get all the users for a particular Section that have the relationship to that section.
Assuming you have the relationship set up correctly on the Section model:
public function users() {
return $this->hasMany('App\User');
}
I suggest you go about this 'backward' and just pull the users from the Section model itself (eager loading allows one query):
$section = Section::with('users')->first();
$usersForThisSection = $section->users;
If you setup a One to Many relationship you can say things like: $user->section to return the section a user belongs to...and $section->users to get a collection of all the users in a section -- the getAllUsers() is redundant in this case.
Make sure your User and Section models contain these methods. Sounds like your migration was setup properly if you have a section_id column on your users table.
More info on one-to-many here: https://laravel.com/docs/5.8/eloquent-relationships#one-to-many
// app/User.php
class User extends Model
{
public function section() {
return $this->belongsTo('App\Section');
}
}
// app/Section.php
class Section extends Model
{
public function users() {
return $this->hasMany('App\User');
}
}
Test out your relationships in php artisan tinker like so...
$user = User::find(1);
$user->section
$section = Section::find(1);
$section->users
you need a unique identifier to receive section_id's users. receive it from url(get) or ajax(post) . if you worry about users access then use "auth"

How to create relationship in Laravel 5 which will collect records of own model mentioned in pivot table?

I have 3 tables users, companies and pivot table with user_id, company_id.
I can't get users, which belongs to my company inside User model.
Tried like
belongsToMany('App\User','companies_users','company_id','user_id' );
but I get relation with wrong users.
Since you are having a belongsToMany relationship between the User and Company, the User belongs to more than one Company. To get users of the companies of a particular User will not be straight forward. If you are sure that is exactly what you want, then do this:
//inside the User model
public function companies()
{
return $this->belongsToMany('Company');
}
//inside the User model
public function companiesusers()
{
$users= new Illuminate\Database\Eloquent\Collection;
foreach($this->companies as $company)
{
$users = $users->merge($company->users->get());
}
return $users->unique();
}
//inside the Company model
public function users()
{
return $this->belongsToMany('User');
}
Then you can get a user's companiesusers like so:
User::first()->companiesusers();

Laravel Relationship Union: One Relationship with two tables in a model

Lets supose this scenery:
We have 3 models -> User, Role and Permission.
Relationships
User has one to many relationship with Role.
Role has many to many relationship with Permission
User has many to many relationship with Permission.
The final purpose to the User -- Permisson relationships is to override the permission assigned to the user through his role. Just an exception for this User.
I am trying to to something like this:
public function permissions () {
return $this->hasManyThrough('App\Permission', 'App\Role')->merge($this->permissionOverrides);
}
In this case when I try to eager load the model permissions Laravel throws an error 'cause permissions is not detected as a relationships.
In the other hand, what if we change User -- Role relationship to many to many?
Thanks a lot for your knowledge!
EDIT
Role Relationships
public function permissions() {
return $this->belongsToMany('App\Permission')->withTimestamps();
}
Permission relationships
public function roles() {
return $this->belongsToMany('App\Role')->withTimestamps();
}
User relationships
public function roles() {
return $this->belongsToMany('App\Role')->withTimestamps();
}
public function permissionOverrides() {
return $this->belongsToMany('App\Permission')->withTimestamps();
}
The question is how to make the permissions() relationship merging the role permissions and the user permissions.
BETTER EXPLANATION
Due to misunderstanding shown in comments I will try to exlain this better. I had set all the relations between App\User and App\Role; I also had set the the relationship between App\Role and App\Permission. I can do right now:
$user->role->permissions;
For obtaining this I have configured the pivot table permission_role which stores the relation.
Thats not the case. What I want is to add one more var to the equation. Now I want to have the ability to override the role permissions adding a relationship between App\User and App\Permission. I have the pivot table permission_user and the relation stablished:
public function permissionsOverride() {
return $this->belongsToMany('App\Permission');
}
The REAL QUESTION is how to obtain all the permissions (both role permissions and overrided permissions in only ONE relationship). I mean merging both relationships.
Why I want to merge relationships? I could do a regular function to do this, but I would want to eager load this relation, Laravel way.
You can try like this, ManyToMany relation between User And Role, similarly ManyToMany relation between Role and Permission.
User Model
public function roles() {
return $this->belongsToMany('App\Role', 'user_role')->withTimestamps();
}
public function permissions() {
return $this->belongsToMany('App\Permission', 'permission_user')->withTimestamps();
}
Role Model
public function users() {
return $this->belongsToMany('App\User', 'user_role')->withTimestamps();
}
public function permissions() {
return $this->belongsToMany('App\Permission', 'permission_role')->withTimestamps();
}
Fetch Data
$user = User::with('permissions','roles','roles.permissions')->find(1);
$permissions = $user->permissions;
foreach($user->roles as $role){
$permissions->merge($role->permissions); //merger collection
}
dd($permissions->all());
For details you can look https://laravel.com/docs/5.6/eloquent-relationships#many-to-many
And for Collection you can look this https://laravel.com/docs/5.6/collections#method-merge

Laravel Relationships: hasManyThrough, belongsTo, belongsToMany

Heyy, I have a Laravel project here, can u guys help me with this question about relationship?
I have the following database structure:
users
id
name
email
password
event
id
description
city_id
block_range
id
event_id
user_block_ranges
user_id
block_range_id
Explanation
users: A normal user authentication table. (has a belongsToMany relationship with user_block_ranges)
event: Stores event info. (has a hasMany relationship with block_range)
block_range: Save blocks of time of event. (has a belongsTo relationship with event)
The real question is: how do I get all the events of the user? Through the user_block_ranges then block_range relationship? Maybe using hasManyThrough?
Thanks in advance.
I believe your models look like this:
User model
class User extends Model
{
public function blockRanges()
{
return $this->belongsToMany('App\BlockRange', 'user_block_ranges', 'user_id', 'block_range_id');
}
}
Block Range model
class BlockRange extends Model
{
public function event()
{
return $this->belongsTo('App\Event');
}
}
To get all events of the user you can do this:
$user = App\User::find(1);
$events = array();
foreach ($user->blockRanges as $block_range) {
$events = $block_range->event;
}

How to create proper relationships?

I have two types of users: Personal and Business. Personal user can belong to Business user. Thats what i created pivot table personal_users_business_user that have user_id,business_user_id.
I have User,PersonalUser and BusinessUser model.
In User model i have this relationship:
public function company()
{
return $this->belongsToMany('App\Models\PersonalUser','personal_users_business_users', 'user_id', 'business_user_id');
}
Im using attach() method :
$user->company()->attach($business_user_id);
It store data in pivot table. Now what i want in view is something like this:
<input class="typeahead form-control" type="text" name="user_company" #if($user->company->approved == 0) ? disabled : '' #endif value="{{$user->company->company_name}}">
But i dont how how to access to those fields from user in pivot table. Any suggestion?
If you need that Business user have multiple personal users, you should use hasMany, belongsTo relationship. In your BusinessUser model you should create method:
public function personalUsers() {
return $this->hasMany(PersonalUser::class);
}
And in your PersonalUser model you should define this method:
public function businessUser() {
return $this->belongsTo(BusinessUser::class);
}
In your migration, for personal users table add following field:
$table->integer('business_user_id')->unsigned()->nullable();
That will make your code right. You don't need pivot table for that relationship.
Set relationship like this
public function company()
{
return $this->belongsToMany('App\Models\PersonalUser','personal_users_business_users', 'user_id', 'business_user_id')
->withPivot(['your_pivot_column']);
}
And now when you code
$user = User::with(['company'])->get();
$user will have the company relationship with the intended pivot column.

Resources