When I create a one-to-one relationship migration, laravel creates a one-to-many relationship. I tried to solve this in different ways and nothing worked.
How can I solve this?
Company:
class Company extends Model
{
public function user()
{
return $this->hasOne(User::class);
}
...
}
User:
class User extends Authenticatable
{
public function company(){
return $this->belongsTo(Company::class);
}
...
}
Migrations:
Schema::create('Company', function (Blueprint $table) {
$table->mediumIncrements('idCompany');
...
});
Schema::create('User', function (Blueprint $table) {
$table->id();
$table->increments('idUser');
$table->unsignedMediumInteger('Company_idCompany')
->unique()
->nullable();
$table->foreign('Company_idCompany')
->references('idCompany')
->on('company')
->onDelete('set null');
...
});
Laravel is creating nothing (on the migration), you always have to manually create the Model relationship (you are using hasOne and belongsTo, so that is 1-to-1) and migrations (you are creating User and Company not following the standards).
So, update your migrations to:
Schema::create('company', function (Blueprint $table) {
$table->id();
...
});
Schema::create('user', function (Blueprint $table) {
$table->id();
$table->increments('user_id');
$table->foreignId('company_id')
->unique()
->nullable();
$table->foreign('company_id')
->references('id')
->on('company')
->onDelete('set null');
...
});
See that I have moved everything to lowercase and snake case, remember to follow Laravel conventions or you are going to have a harder time working with Models...
Then, your relationships are correct:
class Company extends Model
{
public function user()
{
return $this->hasOne(User::class);
}
...
}
class User extends Authenticatable
{
public function company(){
return $this->belongsTo(Company::class);
}
...
}
So, when you do access a relationship, it will work out of the box now.
If you do Company::first()->user, that will return User or null, and if you do User::first()->company, that will return Company or null, there is no 1-to-N.
Related
I got a problem I have done model and migration for 3 tables: movies, actors and actor_movie (pivot)
when Im using from model Actor method movie() it working but don't work from Movie using actor()
class Movie extends Model
{
use HasFactory;
public function actors()
{
return $this->belongsToMany(Actor::class, 'actor_movie');
}
}
class Actor extends Model
{
use HasFactory;
public function movies()
{
return $this->belongsToMany(Movie::class, 'actor_movie');
}
}
movies migration:
public function up()
{
Schema::create('movies', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
actor migration:
public function up()
{
Schema::create('actors', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
Pivot migration:
public function up()
{
Schema::create('actor_movie', function (Blueprint $table) {
$table->bigInteger('movie_id')->unsigned()->index();
$table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
$table->bigInteger('actor_id')->unsigned()->index();
$table->foreign('actor_id')->references('id')->on('actors')->onDelete('cascade');
$table->primary(['actor_id', 'movie_id']);
$table->timestamps();
});
}
As said in the comments, you are running your tests in a Tinker console.
Tinker console loads all your PHP files and dependencies on startup and keep them in memory.
For your code to be refreshed, you need to kill tinker and restart it
i hope you're having a good day.
so i have this ManyToMany relationship where a user can apply to multiple jobs, and a job can have multiple applicants (users).
here is the table schema
Schema::create('applicant_job', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('job_id');
$table->unsignedBigInteger('applicant_id');
$table->unique(['job_id', 'applicant_id']);
$table->foreign('job_id')
->references('id')
->on('jobs')
->onDelete('cascade');
$table->foreign('applicant_id')
->references('id')
->on('default_users')
->onDelete('cascade');
});
and here is the model code.
DefaultUser.php
class DefaultUser extends Model
{
public function user()
{
return $this->morphOne(User::class, 'userable');
}
public function applications()
{
return $this->belongsToMany(Job::class, 'applicant_job', 'job_id', 'applicant_id');
}
}
and Job.php
class Job extends Model
{
public function owner()
{
return $this->belongsTo(BusinessUser::class, 'business_user_id');
}
public function applicants()
{
return $this->belongsToMany(DefaultUser::class, 'applicant_job', 'applicant_id', 'job_id');
}
}
everything seems ok and find, however when i try to save ( a user applying to a job), i get the following error
i'm doing so inside ApplyToJobController.php
class ApplyToJobController extends Controller
{
public function store(Job $job, Request $request) {
$default_user = auth()->user()->userable;
$job->applicants()->attach($default_user->id);
return redirect("/en");
}
}
and, Thank you very much for your answers.
EDIT
i have changed the column names to this
Schema::create('applicant_job', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('job_id');
$table->unsignedBigInteger('default_user_id');
$table->unique(['job_id', 'default_user_id']);
$table->foreign('job_id')
->references('id')
->on('jobs')
->onDelete('cascade');
$table->foreign('default_user_id')
->references('id')
->on('default_users')
->onDelete('cascade');
});
it made it work, im curios any idea why?
Try to switch the order of the foreign keys in the applicants relation declared in the Job model like the example below :
public function applicants()
{
return $this->belongsToMany(DefaultUser::class, 'applicant_job', 'job_id', 'applicant_id');
}
I have a Laravel migration like this
usergroups:
Schema::create('usergroups', function (Blueprint $table) {
$table->integer('id')->primary();
$table->string('name');
$table->string('slug');
});
users:
Schema::create('users', function (Blueprint $table) {
$table->integer('nik')->primary();
$table->string('name');
$table->string('username');
$table->string('password');
$table->string('telp', 15);
$table->integer('usergroup_id');
$table->rememberToken();
$table->timestamps();
});
Schema::table('users', function ($table) {
$table->foreign('usergroup_id')->references('id')->on('usergroups')->onDelete('cascade');
});
User model
public function group()
{
return $this->belongsTo(Usergroup::class, 'id');
}
Usergroup model
public function user()
{
return $this->hasMany(User::class, 'usergroup_id');
}
I get blank data with this
$petugas = User::find(1);
return $petugas->group;
anyone help me, please...
This is not a One to One relationship i.e (user has one phone and one phone belongs to one user)
A group has many users in this case, One to Many relationship
You're migrating the users table twice, move the foreign key to the migration
Schema::create('users', function (Blueprint $table) {
$table->integer('nik')->primary();
$table->string('name');
$table->string('username');
$table->string('password');
$table->string('telp',15);
$table->integer('usergroup_id');
$table->foreign('usergroup_id')->references('id')->on('usergroups')->onDelete('cascade');
$table->rememberToken();
$table->timestamps();
});
Hope this helps
First of all, this is not a One to One relationship. This is a One to Many relationship. The relation you have build in wrong way according to migration files.
The relation code block should look like this.
public function group()
{
return $this->hasMany(Usergroup::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
Some more info:
In your scenario there might be two possible fact.
A user has many groups, but a group is belongs to only one
user.
A group has many users but a user is belongs to only one
group.
Fact 1: In this case the foreign key column should place in groups table. To follow the convention make the foreign column name user_id in groups table. And the code should look like this
public function groups()
{
return $this->belongsTo(Usergroup::class);
}
public function user()
{
return $this->hasMany(User::class);
}
Fact 2: In this case the foreign key column should place in users table. To follow the convention make the make the foreign column name group_id in users table And the relation code should look like this
public function group()
{
return $this->hasMany(Usergroup::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
i got it...
this on user model
public function group()
{
return $this->belongsTo(Usergroup::class,'usergroup_id');
}
and this on usergroup model
public function user()
{
return $this->hasMany(User::class,'usergroup_id');
}
I have the Below Table Structure
Users table
id- integer
name-string
Casefiles table
id- integer
user_id- foreign_key
name-string
Followups table
id- integer
date- date
casefile_id-foreign_key
I'm using the below Relationship between this models
User.php
public function casefiles()
{
if ($this->hasRole(['sales_executive'])) {
return Casefile::where('user_id', $this->id);
}
}
Casefile.php
public function user()
{
return $this->belongsTo('App\User');
}
public function followups()
{
return $this->hasMany('App\FollowUp');
}
Followup.php
public function casefile()
{
return $this->belongsTo('App\Casefile');
}
I want to fetch Users followups directly. How can i achive this ?
you need to use hasManyThrough() in your User.php you can add this,
public function followUps()
{
return $this->hasManyThrough('App\FollowUp','App\Casefile');
}
then you can normally call the followups using User::with('followUps')->find(1)->followUps
I have noticed that you are checking role in your relationship $this->hasRole(['sales_executive'] this may occur error as you are not if the statement is false. I think you take another approached and handle that as well. for more information on hasManyThrough prefer this link
This should be the case for a HasManyThrough Relationship.
In your case it should be
// Followups migration
Schema::create('followups', function (Blueprint $table) {
$table->bigIncrements('id');
$table->date('date');
$table->unsignedBigInteger('casefile_id')->nullable();
$table->timestamps();
$table->foreign('casefile_id')
->references('id')
->on('casefiles');
});
// Casefile migration
Schema::create('casefiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->unsignedBigInteger('user_id')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users');
});
// User.php
public function followups() {
return $this->hasManyThrough(FollowUp::class, Casefile::class);
}
// YourController.php
$user = User::all()->first();
dd($user->followups);
Having some problems retrieving nested relationship data. Here are my models:
class Partner extends Model
{
public function admins()
{
return $this->hasMany(Resource::class)->where('resource_type', 'Admin');
}
}
class Resource extends Model
{
public function details() {
return $this->belongsTo(ResourceDetail::class);
}
}
class ResourceDetail extends Model
{
}
When I try $this->partner->admins[0]->details it's giving null. The sql it generated is: "select * from resource_details where resource_details.id is null". I'm not quite sure why is it null in the query. I must have done something wrong with the relations. I tried $this->partner->with('admins.details')->find($this->partner->id)->toArray();. It's getting the admins, but details is still null. I also tried hasManyThrough, like: return $this->hasManyThrough(ResourceDetail::class, Resource::class)->where('resource_type', 'Admin'); it finds "unknown column". This is my database structure:
Schema::create('partners', function (Blueprint $table) {
$table->increments('id');
});
Schema::create('resources', function (Blueprint $table) {
$table->increments('id');
$table->integer('partner_id')->nullable()->unsigned();
$table->foreign('partner_id')->references('id')->on('partners')
->onUpdate('cascade')->onDelete('set null');
$table->enum('resource_type', constants('RESOURCE_TYPES'))->nullable();
$table->integer('resource_detail_id')->unsigned();
$table->foreign('resource_detail_id')->references('id')->on('resource_details')
->onUpdate('cascade')->onDelete('cascade');
});
Schema::create('resource_details', function (Blueprint $table) {
$table->increments('id');
});
Do I need to change the structure? Or, how can I get the data from current structure? All I want is, a partner has many resources, and a resource has one details.
From that error I think you may be trying to call $this->partner->admins[0]->details from a model that doesn't have an id. What is $this in context to?