How to make a one to one eloquent relation in Laravel? - php

I created my migration by using the artisan command
php artisan make:model Player -m
My migration then looked like this:
public function up()
{
Schema::create('players', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete$
$table->string('username');
$table->timestamps();
});
}
Which left me no errors when I ran
php artisan migrate
I then updated my Player model App/Player.php to include the fillables and one to one relation
class Player extends Model
{
protected $fillable = ['user_id', 'username'];
public function user()
{
return $this->belongsTo('App\User');
}
}
I then ran the Tinker artisan and my output when I try to access the player model is this
>>> User::find(1)->player;
=> null
What am I missing?

Have you done the reverse connection?
Here is the Relation Code
public function player()
{
return $this->hasOne(Player::class);
}

public function user()
{
return $this->belongsTo('App\User','id' */foreign_key */ ,'user_id'*/owner_key*/);
}
i think you forgot to specify the owner_id,
if you dont specify the owner_key of belongsTo the default belongsTo getting is the model id.

User Model
public function player(){
return $this->hasOne('App\Player');
}
Player Model
public function user(){
return $this->belongsTo('App\User');
}

Related

Laravel 7 One To Many Relations?

Below are all of the models, migrations and controller.
Donation Model
class Donation extends Model
{
protected $guarded =[];
public function users(){
return $this->hasMany(User::class);
}
public function items(){
return $this->belongsTo(DonationItems::class);
}
}
Donation Items Model:
class DonationItems extends Model
{
protected $guarded=[];
public function donation(){
return $this->hasMany(Donaition::class);
}
}
Donation Items Migration:
public function up()
{
Schema::create('donation_items', function (Blueprint $table) {
$table->id();
$table->string('category');
$table->timestamps();
});
}
Donation Migration:
public function up()
{
Schema::create('donations', function (Blueprint $table) {
$table->id();
$table->string('item');
$table->unsignedInteger('user_id');
$table->unsignedInteger('donation_item_id');
$table->timestamps();
});
}
In my controller I want to access the items as follows:
$don = Donation::all();
$don->items;
But I'm unable to achieve this.
Its not working because laravel follows one rule for relationships:
Remember, Eloquent will automatically determine the proper foreign key column on the Comment model. By convention, Eloquent will take the "snake case" name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Comment model is post_id.
So you can try by supplying local and foreign id
So it would look something like this
Donation Model
class Donation extends Model
{
protected $guarded =[];
public function users(){
return $this->hasMany(User::class);
}
public function items(){
return $this->belongsTo(DonationItems::class, 'donation_item_id', 'id');
}
}
Donation Items Model:
class DonationItems extends Model
{
protected $guarded=[];
public function donation(){
return $this->hasMany(DonationItems::class, 'id', 'donation_item_id');
}
}
I am writing from my head you might need to swap local and foreign ID's

i want to return the projects of specific user?

I want to return the projects of the authenticated user, but am not getting any. I know the records exist in the database.
This is my model Project:
public function users(){
return $this->hasMany(User::class);
}
this is my model User:
public function projects(){
return $this->hasMany(Projet::class,'user_id');
}
and this is the controller function :
public function projetuser(){
$user = User::find(auth()->user()->id);
return $user->projects;
}
and this my user_projet migration:
public function up()
{
Schema::create('user_projet', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('projet_id');
$table->foreign('projet_id')->references('id')->on('projets')->onDelete('cascade');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('membre')->nullbale();
$table->timestamps();
});
}
You are defining a many-to-many relationship incorrectly. Use belongsToMany() instead of hasMany(). Because your pivot table name is not standard (it should be alphabetic order projet_user) you need to include it in the relationship definition as well.
<?php
use Illuminate\Database\Eloquent\Model;
class Projet extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'user_projet');
}
}
class User extends Model
{
public function projets(){
return $this->belongsToMany(Projet::class, 'user_projet');
}
}
Now in your controller you can do this:
public function projetuser(){
return auth()->user->projets;
}
Your question seems to vary between "projet" and "project." I assumed "projet" was the correct spelling, but try to keep this consistent.
Please note also the typo in your migration: nullbale.

App\Tasks::first()->projects; in artisan tinker returns null, no matter what :(

The following code in tinker returns a null value while it should return the project to which the first task is linked.
App\Task::first()->projects;
Already tried renaming the method names, column names in migrations, tried exiting tinker and logging back in
Project Migration
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('title');
$table->string('description');
$table->timestamps();
});
}
Task Migration
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('project_id');
$table->string('description');
$table->boolean('completed')->default(false);
$table->timestamps();
});
}
Project.php
use App\Task;
class Project extends Model
{
protected $fillable = ['title','description'];
public function tasks(){
return $this->hasMany(Task::class);
}
}
Task.php
use App\Project;
class Task extends Model
{
protected $fillable = [
'completed'
];
public function projects(){
return $this->belongsTo(Project::class);
}
}
If anyone could just review this piece of code and let me know where I have made any conventional\idiotic mistakes (since Im new to route model binding) it would be of great help!
A task belongs to a project, so rename projects to project as it is singular. If you keep projects then provide the column name as second parameter:
public function projects(){
return $this->belongsTo(Project::class, 'project_id');
}
// I suggest this
public function project(){
return $this->belongsTo(Project::class);
}
Your column types are different, for the id of the project you use Big Integer and for the reference you use Integer, so this:
$table->unsignedInteger('project_id');
should be this:
$table->unsignedBigInteger('project_id');
// also good to make the relationship on the Database level:
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');

One-To-One Eloquent Relationship functions

There is something I miss in the eloquent one-to-one relationship:
class MeetingTest extends Model
{
protected $table = 'meeting_tests';
public function meeting() {
return $this->belongsTo('App\Meeting','meeting_id','id');
}
public function observation() {
return $this->hasOne('App\Observation','meeting_test_id','id');
}
public function activity() {
return $this->hasOne('App\TestActivity','activity_id','id');
}
}
The Observation Class is
class Observation extends Model
{
protected $table = 'observations';
public function meetingTest() {
return $this->belongsTo('App\MeetingTest','meeting_test_id','id');
}
}
If I run php artisan tinker and
$mtn = App\MeetingTest::create();
$mtn->save();
$ob = App\Observation::create();
$ob->save;
$mtn->observation()->save($ob);
At this point inside the Observation record I can see the meeting_test_id filled with the correct id of the meetingTest, but if I try:
$mtn->observation
it gives me null; and in the Database there is no observation ID in the observation_id field;
this is the migration:
Schema::create('meeting_tests', function (Blueprint $table) {
$table->increments('id');
$table->integer('meeting_id')->unsigned();
$table->integer('observation_id')->unsigned()->nullable();
$table->integer('activity_id')->unsigned()->nullable();
$table->timestamps();
});
I don't understand what is not correct.
I can see observation_id and activity_id in your meeting_tests table, which makes records in this table the owned side of one-to-one/one-to-many relation. Therefore, both activity and observation relations in MeetingTest should return $this->belongsTo instead of $this->hasOne

Laravel 5.1 Multiple Many to Many Relationship on the Same Model

I seen to of got tangled in Laravel's ORM with the following:
Scenerio: All Users have a Watchlist, the Watchlist contains other Users.
I can't seem the get the relationships to work correctly as they are cyclical, so far I have the following:
class UserWatchlist extends Model
{
protected $table = 'UserWatchlist';
public function Owner() {
return $this->belongsTo('App\User');
}
public function WatchedUsers() {
return $this->hasMany('App\User');
}
}
Schema::create('UserWatchlist', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('Users')->onDelete('cascade');
$table->integer('watched_id')->unsigned();
$table->foreign('watched_id')->references('id')->on('Users')->onDelete('cascade');
$table->timestamps();
});
class User extends Model
{
public function Watchlist() {
return $this->hasOne('App\UserWatchlist');
}
public function WatchedBy() {
return $this->belongsToMany('App\UserWatchlist');
}
}
It is not pulling through the correct in formation i'm expecting. Am I missing something fundamental?
Since UserWatchlist is a pivot table, i suppose you are facing a many to many relationship with both the elements of the relation being the same model (User)
If that is the case, you should not build a model for the pivot table UserWatchlist but all you have to do is to set the relation between the users through the pivot table:
class User extends Model
{
//get all the Users this user is watching
public function Watchlist()
{
return $this->belongsToMany('User', 'UserWatchlist', 'user_id', 'watched_id' );
}
//get all the Users this user is watched by
public function WatchedBy()
{
return $this->belongsToMany('User', 'UserWatchlist', 'watched_id', 'user_id' );
}
}
Check here for more info on many-to-many relationship

Categories