I'm quite new to programming and am struggling to understand how I should specify the eloquent relationships.
I've created a website where there is an event called a "hangout" and a "join" button which allows users to join the event, thereby attaching their user_id to the hangout_id via a pivot table.
Right now I'm very confused as to how I should/can:
specify the relationships between hangout and users;
for a single hangout, display a list of users attending;
for a single user, display a list of hangouts created; and
for a single user, display a list of hangouts they are attending?
Users can create many hangouts, i.e. hasMany, but when they click "join", they also belongToMany hangouts.
Whilst hangouts can only belong to one user but can have many attendees/users.
Can someone point me in the right direction? This is what I have so far...
User.php
public function hangouts()
{
return $this->hasMany('App\Hangout');
}
public function attending()
{
return $this->belongsToMany('App\Hangout');
}
Hangout.php
public function user()
{
return $this->belongsTo('App\User');
}
public function attendees()
{
return $this->hasMany('App\User');
}
Users Table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
$table->boolean('admin');
});
}
Hangout Table:
public function up()
{
Schema::create('hangouts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->string('description');
$table->integer('price')->unsigned();
$table->timestamp('published_at');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
Schema::create('hangout_user', function(Blueprint $table)
{
$table->integer('hangout_id')->unsigned()->index();
$table->foreign('hangout_id')->references('id')->on('hangouts')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
Thanks in advance
Related
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
I have a problem on Laravel 8 when I delete a user I have my 'deleted_at' which is updated in my 'user' table but not the 'deleted_at' of my 'forms' table because I want to delete the forms linked to this user otherwise I have an error because I display his info when he does not exist anymore.
How do I fix this problem please?
I have used the soft delete in the Models
and the 'deleted_at' is updated when I delete the form.
users migration :
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('firstname');
$table->string('lastname');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable()->onDelete('cascade');
$table->string('profile_photo_path', 2048)->nullable();
$table->timestamps();
$table->foreignId('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->softDeletes();
});
}
public function down()
{
Schema::dropIfExists('users', function (Blueprint $table) {
$table->dropColumn('deleted_at');
});
}
forms migration :
public function up()
{
Schema::create('forms', function (Blueprint $table) {
$table->id();
$table->string('title', 100);
$table->text('message');
$table->datetime('date');
$table->string('color');
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
// Schema::dropIfExists('forms');
Schema::table('forms', function (Blueprint $table) {
$table->dropColumn('deleted_at');
});
}
add user to forms migration :
public function up()
{
Schema::table('forms', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::table('forms', function (Blueprint $table) {
$table->dropForeign('user_id')->onDelete('cascade');
});
}
Soft delete won't work on cascading foreign keys. Cascading foreign keys is a feature of sql servers and soft delete is a feature of laravel and needs the laravel context to work.
When you delete it, for the soft deletes to work, you need to call delete on each model of the relation. This is quite easy with collections and higher order functions.
{
$user = User::firstOrFail($id);
$user->forms->each->delete();
$user->delete();
...
}
Thank you very much mrhn,
Thanks to you I have learned a lot!
For those which want the function in the controller which thus makes it possible to remove the user to which belongs thus the id and one thus removes also what is related to him in my case a forms (function in the Models for the cardinalities between entity) :
public function destroy($id)
{
// $users = User::findOrFail($id);
// $users->delete();
$user = User::findOrFail($id);
$user->forms->each->delete();
$user->delete();
return redirect()->route('admin');
}
findOrFail and not firstOrFail ^^'
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
How would you go to create a relationship between the folowing tables:
Users table:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('firstname');
$table->string('surename');
$table->string('address')->nullable();
$table->string('city')->nullable();
$table->string('country')->nullable();
$table->string('postcode')->nullable();
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Setting_type table:
Schema::create('setting_types', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Settings table:
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('value');
$table->timestamps();
});
Setting_type_user table:
Schema::create('setting_type_user', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('type_id')->unsigned();
$table->integer('setting_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('type_id')->references('id')->on('setting_types');
$table->foreign('setting_id')->references('id')->on('settings');
$table->timestamps();
});
This is the result I want to get:
{"id":1,"value":"578943205.jpg","created_at":"2017-07-18 00:00:00","updated_at":null,"pivot":{"setting_id":1,"user_id":1,"type_id":1}}
It depends on many things, but it looks like you want to use many-to-many relationship here.
First, in settings pibot table change it to:
$table->unsignedInteger('user_id');
$table->unsignedInteger('type_id');
It's also a good idea to add foreign key constraints to the table:
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('type_id')->references('id')->on('setting_types');
Then define belongsToMany() relationship in both User and SettingType models. Since you don't follow naming conventions, you have to define foreign keys manually. In the User model:
public function settingTypes()
{
return $this->belongsToMany('App\SettingType', 'settings', 'user_id', 'type_id');
}
And in the SettingType model:
public function users()
{
return $this->belongsToMany('App\User', 'settings', 'type_id', 'user_id');
}
I'm trying to create a ploymorphic many-to-many relationship that also includes an additional relationship. I can't seem to figure out how to get Eloquent to map the additional field to a model.
I have projects, users on those projects, and project roles that dictate permissions for that user on the project.
My tables:
Schema::create('projects', function(Blueprint $table){
$table->increments('id');
$table->timestamps();
$table->softDeletes();
$table->string('name');
$table->integer('possessor_id');
$table->string('possessor_type');
});
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->softDeletes();
$table->string('email');
$table->string('name');
$table->string('username');
});
Schema::create('project_accessors', function(Blueprint $table){
$table->increments('id');
$table->timestamps();
$table->integer('project_id')->unsigned();
$table->foreign('project_id')->references('id')->on('projects');
$table->integer('project_role_id')->unsigned();
$table->foreign('project_role_id')->references('id')->on('project_roles');
$table->integer('entity_id')->unsigned();
$table->string('entity_type');
});
Schema::create('project_roles', function(Blueprint $table){
$table->increments('id');
$table->timestamps();
$table->softDeletes();
$table->string('name');
$table->string('permissions');
$table->integer('project_id')->unsigned();
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
});
I define projects on users like this:
public function projects()
{
return $this->morphToMany('App\Project', 'entity', 'project_accessors')->withTimestamps()->withPivot('project_role_id');
}
I define users and roles on projects like this:
public function roles()
{
return $this->hasMany('App\ProjectRole');
}
public function users()
{
return $this->morphedByMany('App\User', 'entity', 'project_accessors')->withTimestamps()->withPivot('project_role_id');
}
Is there a way to map project_role_id to an actual instance of my Project Role model?