how to define many to many relationship in laravel models? - php

I have two master tables. i.e, users and tasks. Primary key column names are in_user_id for users table and in_task_id for tasks table.
There is relational table users_tasks (to see a task are assigned to which users and a user is assigned with which tasks). Foreign key columns are in_task_id and in_worker_id in users_tasks table.
I want to define relationship of users and tasks (many-to-many) into both models. I have read this doc. But in my case, primary key column is in_user_id in users table. But foreign key column name is in_worker_id in users_tasks table.
So I don't know that how to handle fourth parameter in relationship function (return $this->belongsToMany('App\User', 'users_tasks', 'in_task_id', ?); in Task Model file). Either in_user_id or in_worker_id or something need to define more. If anyone knows the solution, it will be appreciated.

From laravel eloquent documentation on many-to-many relationships
In addition to customizing the name of the joining table, you may also customize the column names of the keys on the table by passing additional arguments to the belongsToMany method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to:
In your case it would be :
return $this->belongsToMany('App\User', 'users_tasks', 'in_task_id', 'in_worker_id');
Now this assumes a few things:
Your user and task model are working properly (since you have non-conventional identifiers you've defined them in your models).
Not sure if its still the case but in previous versions of Laravel, your pivot table (in this case users_tasks) also needs it's own identifier column, typically an auto-incremented id.

Try this
$this->belongsToMany('App\User, 'users_tasks', 'in_worker_id ',
'in_user_id ');
params -> model, relation table, foreignkey, primary key
And also relation tables should be in the alphabetical order. (best way)
It must be tasks_users

Related

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.

How to define a one-way one-to-one relationship in Laravel (5.4) Eloquent?

Think I'm missing something obvious here, but I want to define a one way, one to one relationship from table_1 to table_2, e.g. table1 schema:
Schema::create('table1', function (Blueprint $table) {
// Some field definitions
$table->integer('table2_id')->unsigned();
$table->foreign('table2_id')->references('id')->on('table2')->onDelete('cascade');
});
Table 2 doesn't know anything about Table 1, so just has a bunch of fields defined. Model for Table 1 has:
public function table2() // Get table2 record
{
return $this->hasOne('App\Table2');
}
Questions:
a.) Is that relationship in the record necessary just to be able to lookup the relevant table2 record from a table1 record?
b.) How do I set the relationship in my code? Currently my controller code is:
$table_1_record = new Table1();
// What code here to define the relationship, using Eloquent? Or do I just do:
$table_1_record->table2_id = my_table2_record->id;
// But this just sets it manually doesn't it, rather than using Eloquent?
Thing that is confusing me is in here: https://laravel.com/docs/5.6/eloquent-relationships#one-to-one a bit further down from the link, where it says
Eloquent determines the foreign key of the relationship based on the
model name. In this case, the Phone model is automatically assumed to
have a user_id foreign key.
Applying that example to my code, the thing is I don't want to have to define a table1_id in my Table_2 - but sounds from that quote from the docs that I need to, to find a table2 record from table1...?
c.) Is there any point in this line in the migration: $table->foreign('table2_id')->references('id')->on('table2')->onDelete('cascade'); and indeed using Eloquent at all (I want to do things the proper Laravel way), or shall I just simply manually set table2_id as in question b.) above?
Note: I don't want to define the inverse of the relationship, as I don't need to find a table_1 record from a table_2 record.
Thanks for any help.
Relationships in Eloquent only work in the directions that they are defined. If you want to be able to find Table2 based on the foreign key defined in Table1, you would add a relationship to the Table1 model only. You do not need to define relationships on both models in order to go one direction.
Given your table1 schema, you are actually using the inverse of a one-to-one relationship. table1 is considered a child of table2. Your relationship would look like this:
class Table1
{
public function table2()
{
return $this->belongsTo(\App\Table2::class);
}
}
As for setting the relationship, my recommendation is to simply apply the ID from table2 manually when creating the initial record:
`$table1->table2_id = $table2->id;`
If you're updating a Table1 record, you can use associate(). More info on that here in the docs. Note that this does require you to define the other side of the relationship on Table2. If you don't want to do that, just update the column manually when updating also.
Keep in mind that all of this is powered by Eloquent. Just because you're defining a column value manually instead of using a relationship helper method doesn't mean you're doing something ineffectively or incorrectly.
Is there any point in [the foreign key] line in the migration
This creates a foreign key constraint in the database software itself, and has nothing to do with Eloquent. Eloquent doesn't use or care if you have a foreign key defined. There are benefits to using foreign keys, though, and suggest you look into it further to determine if they're a good idea for your application.

Laravel many to many with custom 'ID' column

I have 2 tables users and teams, that make a relation table user_team.
The user_team table have cod_user and cod_equipe columns and make references to column cod on users, and cod on teams.
This relation returns NULL
User model
public function user_team(){
//belongs to -> pertence a
return $this->belongsToMany('App\User','user_team','cod_user','cod_equipe');
}
Team model
public function team_user(){
//belongs to -> pertence a
return $this->belongsToMany('App\Team','user_team','cod_equipe','cod_user');
}
I think its because Eloquent try to JOIN cod_user with ID on users, but the reference is on cod column.
How can i change this?
Could you clarify what your database schema looks like regarding these tables? In order to make the relations work when defining them explicitly, you need to specify the foreign key from the model in question, followed by the foreign key of the table you want to join. I am confused by the use of 'cod' here as the foreign key mentioned in both users and teams tables. Is the foreign key reference from the users table a field called 'cod', and the same for teams?
If so, you would need to specify that as the foreign key on your users model, and assuming that 'cod_user' is the key in user_team, it would look like this in the User model:
public function userTeam(){
return $this->belongsToMany('App\User','user_team','cod','cod_user');
}
From the laravel docs:
Laravel 5.3 eloquent many-to-many relationships
In addition to customizing the name of the joining table, you may also
customize the column names of the keys on the table by passing
additional arguments to the belongsToMany method. The third argument
is the foreign key name of the model on which you are defining the
relationship, while the fourth argument is the foreign key name of the
model that you are joining to:
return $this->belongsToMany('App\Role', 'role_user', 'user_id',
'role_id');
Additionally, if the primary key on the users or teams table is not named 'id', then you will have to override the convention by defining the variable $primaryKey in your User and Team models.

Laravel - How to use a foreign key to a table with an identifying foreign key?

So I have three tables: users, candidates and logs. Now candidates does not have its own id, it has an identifying foreign key user_id. Looking much like this:
-users-
id
name
etc.
-candidates-
user_id
type
etc.
Now I want to have a table logs that has a one-to-many relation with candidates, being that a candidate can have zero or more logs. So I want to have a foreign key to candidates, something like candidate_id. However, putting it like this and Laravel won't automagically understand the relation. What should I name the foreign key from logs to candidates to make Laravel understand the relationship?
I think the simplest thing would be to give candidates its own incremental id and then have two relationship tables, candidate_user and candidate_log. It would be set up according to Laravel docs
Your candidates table must have a primary key.
There's no need to have an incremental ID, but you shouldn't leave the table without a primary key.
Once you define a primary key, you can use it as your reference.
Laravel will try to guess your foreign_key name:
https://laravel.com/docs/5.2/eloquent-relationships#one-to-many
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.
If your primary key is not the "id" column, you should use the protected $primaryKey and the public $incrementing properties to describe your primary key in your Eloquent Model.

hasMany vs belongsToMany in laravel 5.x

I'm curious why the Eloquent relationship for hasMany has a different signature than for belongsToMany. Specifically the custom join table name-- for a system where a given Comment belongs to many Roles, and a given Role would have many Comments, I want to store the relationship in a table called my_custom_join_table and have the keys set up as comment_key and role_key.
return $this->belongsToMany('App\Role', 'my_custom_join_table', 'comment_key', 'role_key'); // works
But on the inverse, I can't define that custom table (at least the docs don't mention it):
return $this->hasMany('App\Comment', 'comment_key', 'role_key');
If I have a Role object that hasMany Comments, but I use a non-standard table name to store that relationship, why can I use this non-standard table going one way but not the other?
hasMany is used in a One To Many relationship while belongsToMany refers to a Many To Many relationship. They are both distinct relationship types and each require a different database structure - thus they take different parameters.
The key difference is that in a One To Many relationship, you only need the two database tables that correspond to the related models. This is because the reference to the relation is stored on the owned model's table itself. For instance, you might have a Country model and a City model. A Country has many cities. However, each City only exists in one country. Therefore, you would store that country on the City model itself (as country_id or something like that).
However, a Many To Many relationship requires a third database table, called a pivot table. The pivot table stores references to both the models and you can declare it as a second parameter in the relationship declaration. For example, imagine you have your City model and you also have a Car model. You want a relationship to show the types of cars people drive in each city. Well, in one city people will drive many different types of car. However, if you look at one car type you will also know that it can be driven in many different cities. Therefore it would be impossible to store a city_id or a car_id on either model because each would have more than one. Therefore, you put those references in the pivot table.
As a rule of thumb, if you use a belongsToMany relationship, it can only be paired with another belongsToMany relationship and means that you have a third pivot table. If you use a hasMany relationship, it can only be paired with a belongsTo relationship and no extra database tables are required.
In your example, you just need to make the inverse relation into a belongsToMany and add your custom table again, along with the foreign and local keys (reversing the order from the other model).
Try to understand with text and a figure.
One to One(hasOne) relationship:
A user has(can have) one profile. So, a profile belongs to one user.
One to many(hasMany):
A user has many(can have many) articles. So, many articles belong to one user.
Many to many(BelongsToMany):
A User can belong to many forums. So, a forum belongs to many users.

Categories