two foreign keys, how to map with laravel eloquent - php

I have two tables in MySQL, where the first one is called users and the second one is called games. The table structure is as follows.
users
id (primary)
email
password
real_name
games
id (Primary)
user_one_id (foreign)
user_one_score
user_two_id (foreign)
user_two_score
My games table is holding two foreign relations to two users.
My question is how do I make the model relations for this table structure?? - According to the laravel documentation, I should make a function inside the model and bind it with its relations
for instance
public function users()
{
$this->belongsTo('game');
}
however I can't seem to find anything in the documentation telling me how to deal with two foreign keys. like in my table structure above.
I hope you can help me along the way here.
Thank you

A migration:
$table->integer('player1')->unsigned();
$table->foreign('player1')->references('id')->on('users')->onDelete('cascade');
$table->integer('player2')->unsigned();
$table->foreign('player2')->references('id')->on('users')->onDelete('cascade');
And a Model:
public function player1()
{
$this->belongsTo('Game', 'player1');
}
public function player2()
{
$this->belongsTo('Game', 'player2');
}
EDIT
changed 'game' to 'Game' as user deczo suggested.

Unfortunately the way you have this setup is not likely to work in the current context. You may have more luck with the belongsTo method, but again that only supports one relationship.
You could implement a user1() belongsTo, a user2() belongsTo and finally just declare a non eloquent function to return both (something like $users = array($this->user1(), $this->user2())

Related

How do I handle multiple pivot relationships in Laravel?

In my app, you can create lists of roles that are attached to contacts. So you can assign the contact "Bob" the roles of "Gardener" and "Pet Sitter". Then you can create the list "People" and add "Gardener (Bob)" and "Pet Sitter (Bob)" to it.
I have the following tables:
contacts
id
name
roles
id
name
contact_role (pivot)
id
contact_id
role_id
lists
id
name
contact_role_list (pivot)
id
contact_role_id
list_id
Everything was working smoothly until the second pivot table linked to the first pivot table. My pivot tables are (currently) not having any models so I'm not sure if there is a built-in feature to tackle this in Laravel or if I need to think differently.
I currently have this in my List model:
public function list_roles(): BelongsToMany
{
return $this->belongsToMany(XYZ::class, 'contact_role_list', 'list_id', 'contact_role_id');
}
Is this even close? What do I put where it says XYZ::class?
Ok, so the below is doing what I want, but is there an even better way to do it? The key to solving my problem was to create a Model for ContactRole and changing extends Model to extends Pivot.
I placed this in my List Model:
public function list_roles(): BelongsToMany
{
return $this->belongsToMany(ContactRole::class, 'contact_role_list', 'list_id', 'contact_role_id');
}
And this in my ContactRole Model:
public function contact(): BelongsTo
{
return $this->belongsTo(Contact::class);
}
Now I could reach the contact data by using something like this: List::first()->contact_roles->first()->contact
Any way to use with, pivot or similar to tidy this up even more? Thanks!
I like to approach these issues in terms of Models rather than pivots. I think many new Developers in Laravel get over obsessed with what's going on in the Database which is fine, but theres a lot of Magic going on so you can write very simple code that does a lot of Heavy lifting, so that being said if I fully understand your problem
You have a Contacts Model
This model can have many roles
so in your contacts Model you need a role relationship
public function roles()
{
return $this->belongsToMany(Roles::class);
}
next of course you have a role Model (pun intended)
your each role can have many list
public function lists()
{
return $this->hasMany(List::class)
}
then the idea is now that you have roles on contacts and lists on roles you should be able to have many lists through contact
public function lists()
{
return $this->hasManyThrough(List::class, Role::class);
}
I've done similar things before and for your description it seems like that's the approach you might need to take.

Laravel: How to add Relationship in Model when my Foreign keys are in array?

I have a table where I need to save the ids in array, you can see the items in
events_who is a foreign keys. Any solution where I can create a Relationship in my Model to get the data from the foreign keys? I tried belongsToMany and it doesn't work. :(
Any suggestions?
Let's assume we are having 2 models: Event and Person
And a Person can participate to multiple Event
Based on the mentioned relationships, you need to create a pivot table called event_person and define two belongsToMany() relationships in both models:
In the Person model, the relationship will look like:
public function events()
{
return $this->belongsToMany(Event::class, 'event_person');
}
Laravel / MySQL (Relational Database) don't really work this way. You should check out Many to Many Relationships in this case.
Example table schema/layout:
users
|id|name|password|
events
|id|title|body|
event_user (pivot table)
|event_id|user_id|
Usually there won't be an array in a column, you should use tables instead. Besides, normally a foreign key would be a table name(singular) following by _id.

One to many relation in pivot table in laravel?

I have pivot table and it has one to many relationship with another table, So I am confused with database design and relationship in Laravel Elequent.
Is this right way to design databse or should I create id as primary key for award_entries and use it is foreign key in entry_files. ?
If I am following existing design (first one), how will I write relation in Laravel eloquent?
Here how your relation will look like. You may need to change model or columns name.
In award_entry model:
public function entry_file() {
return $this->belongsTo('App\Models\entry_file','award_entries_award_id');
}
And in Entry_file model:
public function award_entries(){
return $this->hasMany('App\Models\award_entries','award_entries_award_id');
}

Multiple "statuses" for many-2-many table relationship in a Laravel Data Model? Best approach?

I am new to Laravel (only been coding a few months). I've created a DB model that connects two tables "Players" and "Teams" via a pivot table.
class Player extends Model
{
public function teams()
{
# With timetsamps() will ensure the pivot table has its created_at/updated_at fields automatically maintained
return $this->belongsToMany('p4\Team')->withTimestamps();
}
}
class Team extends Model
{
public function players()
{
return $this->belongsToMany('p4\Player')->withTimestamps();
}
}
Players can be members of (many) teams, "own" teams, be "recruited" to teams, and be "rejected" from teams. Both Teams and Players can initiate requests for each of these statuses, allowing the other party to confirm/reject. In each case, they should be linked and can only occupy one of the four statuses. What is the best way to link these two tables such that the relationship between any two instances can be given 4 "statuses"?
I need to give the users (whom control teams and players in this open management/recruitment environment), the ability to request/approve classification in each of the "statuses".
It strikes me that the cleanest way to do this would be to use a single pivot table that "assigns" these given statuses to each linked ID pair. I, however, have only seen simpler examples of this concept executed and am as a result unsure as to what the best way to do that is. I would appreciate some guidance here.
Schema::create('player_team', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
# `book_id` and `tag_id` will be foreign keys, so they have to be unsigned
# Note how the field names here correspond to the tables they will connect...
# `book_id` will reference the `books table` and `tag_id` will reference the `tags` table.
$table->integer('player_id')->unsigned();
$table->integer('team_id')->unsigned();
# Make foreign keys
$table->foreign('player_id')->references('id')->on('players');
$table->foreign('team_id')->references('id')->on('teams');
});
*Again, I'm pretty fresh. Apologies if this has an obvious solution I'm just missing.
If I understood you correctly, you can add status column to a pivot table:
$table->tinyInteger('status')->unsigned();
Don't forget to add withPivot() to relations:
return $this->belongsToMany('p4\Player')->withPivot('status')->withTimestamps();
You can access this column with pivot and set or unset it by adding an array to attach() and detach() methods:
$team->players()->attach($playerId, ['status' => 3]);
Read more about it in docs:
https://laravel.com/docs/5.3/eloquent-relationships#many-to-many
https://laravel.com/docs/5.3/eloquent-relationships#inserting-and-updating-related-models

Eloquent: How to define a one-to-one relationship on the same model

Say I have a Tennis players model, and each player has a mate they're tied to for doubles games. How would I define that relationship in Eloquent? I'm used to the usual scenario in the docs (and have seen the same in many codebases) where the one-to-one relationship points to an entry in another table which makes it straight-forward where to put hasOne() and belongsTo().
A player can only have one mate plus no two players share the same mate, and their relationship is determined by the value in a mate_id field. So ideally I'd want to do $player->mate to get the mate.
So what goes in the mate() method that I'll add on the Player model, to satisfy the requirement of a hasOne() and belongsTo() as shown in the docs? Thanks
Wouldn't hasOne relation work here?
Try this in your model
public function mate()
{
return $this->hasOne('Player', 'mate_id');
}
I don't think we would need the reverse relationship, as doing $player->mate() on any one player will give the other.
You need to make new table, which might be called "mate".
mate
id
player_id (unique, not null)
player_id (unique, not null)
Then you pair them from Players table with belongsToMany().
Unique constraint says that a Player cant be in more than 1 pair.
The one-to-one as I want it works when I define only the belongsTo(), it won't work if I use hasOne() as in the other answers.
public function mate()
{
return $this->belongsTo('App\Player', 'mate_id');
}

Categories