Laravel: Best way to have multiple user relations on same model - php

I have a polling app.
Admins can create new polls. I have a belongsTo relation in my polls Model so I can later track which user created the poll.
Now I want to allow the poll admin to add users from the list of registered users so that only these users can access the poll.
Adding another hasMany relation to users to the poll model does not work because it already has the belongsTo. But what would the best way be? Simply add a field to my poll model and fill it with a list of user ids? Auth? But does that make sense for possibly hundreds of polls?
I feel like I am not seing an obvious solution here...
Thanks
Poll Model
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Poll extends Model
{
use HasFactory;
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
}
User model
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, HasRoles;
...
/**
* poll relationship
*/
public function polls()
{
return $this->hasMany(Poll::class);
}
}
Poll migration
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('polls', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('name');
$table->timestamp('start_time')->nullable();
$table->timestamp('end_time')->nullable();
$table->timestamps();
$table->index('user_id');
});
}
}
User migration
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
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();
});
}
}

You might want to create a a different, many to many relationship between polls and users. I call it participants.
table poll_user
poll_id
user_id
class Poll extends Model
{
public function participants()
{
return $this->belongsToMany(User::class, 'poll_user');
}
}

Related

Eloquent relationship between Hospital and Unit models in Laravel is not working as expected

I am trying to establish a one-to-many relationship between Hospital and Unit models in Laravel. A hospital can have many units, while a unit belongs to one hospital. However, the association doesn't seem to work as expected.
Here is my Hospital model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Hospital extends Model
{
use HasFactory;
protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;
public function units()
{
return $this->hasMany(Unit::class);
}
}
And here is my Unit model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Unit extends Model
{
use HasFactory;
protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;
public function hospital()
{
return $this->belongsTo(Hospital::class);
}
public function benefits()
{
return $this->belongsToMany(Benefit::class, 'benefit_unit');
}
}
Here is the code that I use to associate a hospital with a unit:
$unit = Unit::create($unitData);
$unit->hospital()->associate($hospital)->save();
manual code works for me:
$hospitalUnitData = [
'hospital_id' => $hospital->id,
'unit_id' => $unit->id,
];
DB::table('hospital_unit')->insert($hospitalUnitData);
schemas:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateHospitalsTable extends Migration
{
public function up()
{
Schema::create('hospitals', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('hospitals');
}
}
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUnitsTable extends Migration
{
public function up()
{
Schema::create('units', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->uuid('hospital_id');
$table->timestamps();
$table->foreign('hospital_id')->references('id')->on('hospitals');
});
}
public function down()
{
Schema::dropIfExists('units');
}
}
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateHospitalUnitTable extends Migration
{
public function up()
{
Schema::create('hospital_unit', function (Blueprint $table) {
$table->id();
$table->uuid('hospital_id');
$table->uuid('unit_id');
$table->timestamps();
$table->foreign('hospital_id')->references('id')->on('hospitals')->onDelete('cascade');
$table->foreign('unit_id')->references('id')->on('units')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('hospital_unit');
}
}
Pivot table is only needed for many-to-many relationship.
For one-to-many relationship, all you need is a refernce ID on the model that belongs to a certain, model,
Simply think of them like this, you have hospital and unit model unit,
how do you get all units of hospital A? You simply query the Unit table with hostpal_id of hospital A (HasMany)
how do you determine what is the hospital of a unit? you get the hospital based on hostpal_id stored on that unit column (BelongsTo)
you see, you dont need an intermediate (pivot) table to connect hospital and unit.
when you call this $unit->hospital()->associate($hospital)->save(); its not updating your hospital_unit table because it updates the relationship of your Hospital and Unit relationship which is one-to-many,
which mean its just updating/adding the Hospital id to the hospital_id from the Unit table and not creating pivot entry in hospital_unit table as the relationship is not many-to-many

Why new columns are not migrated, and relationships are not applied in Laravel?

I am working on a Laravel project with PhpMyAdmin and I am quite new to Laravel, I have created tables with models, and already migrated them, now I need to add new columns but when I add the columns and then migrate it shows that noting there to be migrated
Also same thin for the relationships, I applied 1-1 between 2 tables and migrated, but the database is not updated, and from time to time I got an error of duplicating session table as well, how to solve this?
Students table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('students', function (Blueprint $table) {
$table->id();
$table->string(column:"Name");
$table->string(column:"Semester");
$table->unsignedBigInteger('project_id')->nullable(false);
$table->foreign('project_id')->references('id')->on('projects');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('students');
}
};
Projects table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->id();
$table->string("Title");
$table->date("Start Date");
$table->date("End Date");
$table->date("Type");
$table->integer("Duration");
//$table->unsignedBigInteger("lecturer_id");
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('projects');
}
};
Project model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class project extends Model
{
use HasFactory;
public function getStudnet(){
return $this->belongsTo('App\project');
}
}
Student model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class student extends Model
{
use HasFactory;
public function getProject(){
return $this->hasOne('App\project');
}
}
Once you have migrated the table there are 2 options to add new columns/new conditions/ new modifications.
1- Create a new migration & associate it with the existing one.
2- Run command: php artisan migrate:fresh
it will drop all your tables and then again migrate them and the changes reflect.
In Laravel, we don't add/modify columns in migrated files. We use separate migration for it. Or else you can use
php artisan migrate:fresh
This will drop all your data and rebuild the table migration. But creating separate migration is recommended.
and the relationship namespace is wrong
return $this->belongsTo('App\project');
should be
return $this->hasOne('App\Models\Project');

Why am i getting this error when i try to add foreign keys on Invoice table?

I have two tables users and invoices. This is the up function for the users migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('email')->unique();
$table->string('phone')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('comentarii');
$table->rememberToken();
$table->timestamps();
});
}
This is the up function for the invoices migration:
public function up()
{
Schema::create('invoices', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('user_id');
$table->foreign('user_id')->refferences('id')->on('users');
$table->integer('InvoiceNumber');
$table->dateTime('date');
$table->string('serviceInvoiced');
$table->timestamps();
});
}
All I am trying to do is to make a one to many relationship as in a user can have multiple invoices.
Here is the User model:
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $guarded = [];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getInvoices()
{
return $this->hasMany(Invoice::class);
}
}
Here is the Invoice model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
use HasFactory;
protected $guarded=[];
public function getUsers()
{
return $this->belongsTo(User::class);
}
}
What am I doing wrong? I watched multiple tutorials already. Here are the errors that im getting:
The columns need to be of the same type. id() is an alias of bigIncrements(), so
$table->unsignedInteger('user_id');
should be
$table->unsignedBigInteger('user_id');
Also note: it's ->references('id'), not ->refferences('id')
More on Available Column Types
You have two issues:
You have a typo in your migration statement
$this->id() make unsignedBigInteger so user_id should be unsignedBigInteger
Alter you migration lines to this:
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users'); //references not refferences

Problem when I run the 'artisan:migrate' in a 'Many to One' relationship

I have the 'people' table and each 'person' must have some 'furniture'.
I run 'migrate' and this error message appears:
QLSTATE[HY000]: General error: 1005 Can't create table
my_database.furniture (errno: 150 "Foreign key constraint is
incorrectly formed") (SQL: alter table furniture add constraint
furniture_person_id_foreign foreign key (person_id) references
people (id))
LARAVEL VERSION: 5.8
Here are my files:
2021_04_15_132404_create_persons_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePeopleTable extends Migration
{
public function up()
{
Schema::create('people', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('cpf');
$table->string('phone');
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('people');
}
}
2021_04_16_233323_create_furniture_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFurnitureTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('furniture', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('type');
$table->string('name');
$table->integer('person_id')->unsignedBigInteger()->nullable();
$table->foreign('person_id')->references('id')->on('people');
$table->softDeletes();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('furniture');
}
}
Person.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Person extends Model
{
use SoftDeletes;
}
Furniture.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Furniture extends Model
{
use SoftDeletes;
}
Does anyone know how to solve?
Remove $table->integer('person_id')->nullable(); from CreateFurnitureTable migration, leave the unsignedBigInteger since that's the integer column type. Just using that method us also recommended by Laravel as per the documentation on foreign keys for Laravel 5.8
$table->unsignedBigInteger('person_id');
$table->foreign('person_id')->references('id')->on('people');

user_id is not taking the value provided

The migrations file look like below
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title')->unique();
$table->text('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
but the posts table in the database is having 0 as value.
The database is populated through the web.php code below. I need the user_id to have values 1 and 2 in the database posts.
Route::get('/create',function (){
$post=Post::create(['title'=>'lara vel','body'=>'laravel is good for php','user_id'=>1]);
$post=Post::create(['title'=>'spri ng','body'=>' spring is good for java','user_id'=>2]);
});
It's very Simple
just Go to your Post model
when you use create method to insert data you must be use fillable propery in your model.
so if you not have an Post model so create post Model and paste this code inside your Post Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = 'posts';
protected $fillable = [
'user_id', 'title','body'
];
}

Categories