Eloquent Query with Pivot Table - laravel

I have a question about how to generate a query with eloquent and I would appreciate any help from you.
I have 4 tables in my database:
1. modules
2. roles
3. module_rol (pivot table)
4. regions
Structure of the tables:
modules:
id int
name string
region int
active bool
roles
id int
name string
module_rol
rol_id int
module_id int
regions
id int
name string
I need to get all the values ​​from the modules table with some conditions for example ..
public function getUserModules($rol, $region)
{
// Return all modules to which that role is allowed to access and have that region defined
}
While waiting for some help, thank you very much in advance
EDIT 1:
Schema::create('regions', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('modules', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('region')->unsigned();
$table->boolean('active')->default(true);
$table->timestamps();
$table->foreign('region')
->references('id')->on('regions')
->onDelete('cascade');
});
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('module_rol', function (Blueprint $table) {
$table->increments('id');
$table->integer('rol_id');
$table->integer('module_id');
$table->timestamps();
$table->foreign('rol_id')
->references('id')->on('roles')
->onDelete('cascade');
$table->foreign('module_id')
->references('id')->on('modules')
->onDelete('cascade');
});

You need to define ManyToMany relationship between Module and Role using pivot table
Module Model
public function roles(){
return $this->belongsToMany(Role::class, 'module_rol');
}
public function region(){
return $this->belongsTo(Region::class, 'region');
}
Role Model
public function modules(){
return $this->belongsToMany(Module::class, 'module_rol');
}
Fetch Data
public function getUserModules($role, $region)
{
// Return all modules to which that role is allowed to access and have that region defined
$modules = Module::where('region', $region->id)
->whereHas(['roles' => function($query) use ($role) {
return $query->where('role_id', $role->id)
}])->get();
return $modules;
}
Details https://laravel.com/docs/5.6/eloquent-relationships#many-to-many

Related

Assigning one or more clinicians (user role_id =2) to patient in Laravel (Many to Many)

My app have a few misunderstanding i need help with. These are listed as follows:
A clinician can be assigned to one or more patient/s by the admin.
In a clinician backend he/she can only view profiles of the clients assigned by the admin.
IN User Model
public function patients()
{
return $this->belongsToMany('App\Patient')->withTimestamps();
}
In Patient Model
public function users()
{
return $this->belongsToMany('App\User')->withTimestamps();
}
In User Table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('username')->unique();
$table->string('slug')->unique();
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->string('phone')->unique();
$table->string('address');
$table->string('gender');
$table->integer('role_id')->default(2);
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
In Patient Table
public function up()
{
Schema::create('patients', function (Blueprint $table) {
$table->id();
$table->string('username')->unique();
$table->bigInteger('user_id')->unsigned();
$table->string('slug')->unique();
$table->string('profilePic');
$table->string('first_name');
$table->string('last_name');
$table->string('dob');
$table->string('gender');
$table->string('parent_name');
$table->string('parent_number');
$table->string('parent_email');
$table->boolean('status')->default(false);
$table->boolean('is_approved')->default(false);
$table->timestamps();
});
Schema::table('patients', function(Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
});
}
Kindly Assist
This is the example for a pivot table:
Rules:
Need a migration to a third table
The table's name need to be in singular and order by alphabetical order
Ex.: patient_user with patient_id and user_id
No need Model for this table
Add user as patient
$user = User:find(5);
$user->patients()->attach(1);
In your table patient_user you will have a record: user_id

Property [roles] does not exist on this collection instance. in a many-to-many relationship

Hello I am learning relationship many to many I read the official documentation and use the conventions,
but I can't make the relation many to many I get the error that the property does not exist.
how can I solve that?
Migrations
Schema::create('role_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->foreignId('role_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
}
User
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Roles
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Models:
User
public function roles(){
return $this->belongsToMany(role::class, 'role_user', 'user_id', 'role_id');
}
Role
public function users(){
return $this->belongsToMany(User::class, 'role_user','role_id','user_id');
}
query:
$v = User::get();
dd($v->roles);
$v = User::get(); returns a collection of users. If you get one user, for example, User::find(1) you will have access to the roles for this specific user.
Another option is
$users = User::with('roles')->get();
foreach ($users as $user) {
$userRoles = $user->roles;
}

Laravel get data from pivot table many to many relationship

Tables with relationship
I want to get the classes for specific notes. Here note id and class id are in a pivot table.
Note.php
public function classes()
{
return $this->belongsToMany(MyClass::class);
}
MyClass.php
public function notes()
{
return $this->belongsToMany(Note::class);
}
I am saving the data successfully by
$note->classes()->attach($request->class);
MyClass Migration
Schema::create('my_classes', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
$table->boolean('isDeleted')->default(false);
$table->dateTime('deletedAt')->nullable();
});
Notes Migration
Schema::create('notes', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('description')->nullable();
$table->string('image')->nullable();
$table->timestamps();
$table->boolean('isDeleted')->default(false);
$table->dateTime('deletedAt')->nullable();
});
my_class_note migration
Schema::create('my_class_note', function (Blueprint $table) {
$table->bigIncrements('id');
$table->foreignId('my_class_id')->constrained();
$table->foreignId('note_id')->constrained();
$table->timestamps();
});
Needed help on getting classes for a specific note. One note can have many classes.
You can simply access it by using the relationship property, there always will be if you have defined a relationship.
// returns a collection of classes
$classes = Note::find(1)->classes;
In your controller.
return view('yourview', ['classes' => $classes]);
In your view.
#foreach($classes as $class)
<p>{{$class->name}}</p>
#endforeach

Trying to get property of non-object when i try to $blog->user->name

in my model user
public function blogs(){
return $this->hasMany('App\Blog');
}
in my model blog
public function user(){
return $this->belongsTo('App\User','user_id');
}
in my BlogController
public function show($id)
{
$blog = Blog::find($id);
dd($blog->user->name);
return view('admin.pages.blogs.show',compact('blog'));
}
database table user ( id,role_id,name)
if role_id = 1(admin) then result $blog->user->name is null
if role_id = 2(author) then result $blog->user->name is name of user
how can i fix when role_id = 1
You need to remove user_id from Blog model.
public function user()
{
return $this->belongsTo(User::class);
}
UPD. In any case role_id does not matter. So you need to make sure DB contains related records. For example:
blogs:
id user_id text
1 123 '...'
users:
id name
123 'Linh'
First of all you change blogs users and roles migration.
blogs migration
Schema::create('blogs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('title');
$table->string('slug')->unique();
$table->string('image');
$table->string('body');
$table->tinyInteger('status')->default(0);
$table->tinyInteger('is_approved')->default(0);
$table->integer('view_count')->default(0);
$table->timestamps();
});
users migration
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('role_id')->default(2);
$table->foreign('role_id')->references('id')->on('roles');
$table->string('name');
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('password');
$table->string('image')->default('default.png');
$table->text('about')->nullable();
$table->rememberToken();
$table->timestamps();
});
roles migration
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('slug')->unique();
$table->timestamps();
});
User model
public function blogs(){
return $this->hasMany('App\Blog');
}
Blog model
public function user(){
return $this->belongsTo('App\User');
}
BlogController
public function show($id)
{
$blog = Blog::find($id);
dd($blog->user->name);//check
return view('admin.pages.blogs.show',compact('blog'));
}

BadMethodCallException: Trying to list all partners with the categories laravel

I'm experiencing the following:
Goal: I would like to list all partners and the categories they belong to. Basically, it's a many to many relationship.
Below is the code:
Partner Categories Table Migration
public function up()
{
Schema::create('partcats', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('partcatnameP')->unique();
$table->unsignedBigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
Partners Table Migration
public function up()
{
Schema::create('partners', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('partnername');
$table->string('regnumber')->unique();
$table->unsignedBigInteger('activestatus_id')->unsigned();
$table->foreign('activestatus_id')->references('id')->on('activestatuses');
$table->unsignedBigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
Partner_Category Migration
public function up()
{
Schema::create('partner_partcat', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('partner_id')->unsigned();
$table->foreign('partner_id')->references('id')->on('partners')->onDelete('cascade');
$table->unsignedBigInteger('partcat_id')->unsigned();
$table->foreign('partcat_id')->references('id')->on('partcats')->onDelete('cascade');
$table->timestamps();
});
}
Models are as shown below:
Partcat Model
public function partners()
{
return $this->belongsToMany('App\Partcat','partner_partcat');
}
Partner Model
public function partcats()
{
return $this->belongsToMany('App\Partcat','partner_partcat');
}
and the Partners Controller is as shown below:
public function index()
{
//
$partners = Partner::all()->partcats();
// dd(Partner::all()->partcats());
return view('partners.index',['partners'=>$partners]);
}
This is where I'm trying to retrieve the list of partners and its related categories. However, I get a BadMethod call error.
You can use the following method
$partners = Partner::with('partcats')->get();
https://laravel.com/docs/5.6/eloquent-relationships#eager-loading
A many to many pivot table typically has the id for both tables it is relating.
The Partner_Category migration you have posted only seems to contain a partner_id. You may need to add in the category_id.
public function up()
{
Schema::create('partner_partcat', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('partner_id')->unsigned();
$table->unsignedBigInteger('partcat_id')->unsigned();
$table->timestamps();
$table->foreign('partner_id')->references('id')->on('partners')->onDelete('cascade');
$table->foreign('partcat_id')->references('id')->on('partcats')->onDelete('cascade');
});
}

Resources