I know you can define table relationships fairly easy with $this->belongs_to(), $this->has_many() etc, but what i don't understand is how the relationship table is created; the table that binds the two tables together (i forgot what the term is called).
Let's say i'm creating a users table. I want that user to belong to a certain "Role". There are multiple roles, and every role can have multiple users. I will need to also create a roles table for that. So far, so good.
But after reading the documentation, it says i should add the $this->belongs_to() in the model, not the migration itself. When, and how is the relationship table created? If i create the roles and users tables, and add $this->belongs_to('roles') to the users model, and $this->has_many('users') to the roles model, will the middle table be created automatically?
When creating a migration you can specify foreign keys on your tables,
i.e.
public function up()
{
Schema::table('roles', function(Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
//rest of fields then...
$table->foreign('user_id')->references('id')->on('users');
});
}
This will create a foreign key on the user_id column on the roles table.
The benefits of foreign keys is that when an update or delete is made the foreign key table will be automatically updated or "cascaded" great description found here
As described on the Laravel documentation you could also specify your cascading on update using the following syntax
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
I would do a bad job of trying to explain it better than the documentation does so please have a read through the "Relationships" section of the Eloquent ORM documentation to see how its done.
It looks like a few of the initial questions were never answered, i.e. "When, and how is the relationship table created" & "will the middle table be created automatically":
As far as I am aware, these tables need to be created manually. So create the migration file like so:
Laravel 5
php artisan make:migration create_role_user_table
Laravel 4
php artisan migrate:make create_role_user_table
Note that the names are singular, and are presented in alphabetical order.
Then in the migration something like:
public function up()
{
Schema::create('role_user', function($table) {
$table->increments('id');
$table->integer('role_id');
$table->integer('user_id');
$table->timestamps();
});
}
Hope that helps. I'm not sure if the timestamps are needed in Pivot Tables or not, so please experiment.
Though its an old Post, I though I can contribute something updated. For Laravel5, Jeffrey Way has developed a package Laravel5 Generators-extended which enhance the generator capability of php artisan for
make:migration:schema
make:migration:pivot
make:seed
For many-to-many relation between users and role, you can just use
php artisan make:migration:pivot users role
and it will generate the required migration class. You don't need to code manually for this.
As far as I know, no relationship table will be created. What you will need to do is have a role_id on your users table, so that when you create a user, the ID of the role will be stored there. This will enable you do select all users where role_id == '1' or whatever it may be.
For example:
$admins = User::where('role_id', '=', 1);
Where on the ROLES table the record with ID='1' is admin.
So again to answer your question, no relationship table is created, instead the relationship exists within your two tables in the form of a role_id column for each user. Out of interest, are you using foreign keys?
If you want to have a relationships table you could create one called user_roles or something and store the role_id and user_id in there, however I think its easier to use the above method as then you can use all the Laravel/Eloquent goodness.
Hope this helps :)
This video helped me.
https://laracasts.com/series/laravel-5-fundamentals/episodes/14
What was surprising for me was that only one side of the relationship needs pointer_id in migration table, not both. For example, if we have Author with many Articles, we only add
$table->integer('author_id')
to article migration and thats it.
I know this is an old post but as I had the same question in mind. I've found the solution in the Laravel manual (5.0) where it is described that for this particular many-to-many relationship you can create the table manually and then declare the type of relationship into Model in this way:
return $this -> belongsToMany('App\<Model>', '<table_created_manually>');
or if you want to use specific associated keys:
return $this -> belongsToMany('App\<Model>', '<rel_table1_table2>' '<table1>_id', '<table2>_id');
Hope this can help.
Related
I have some doubts about how to design a model whith a relation bewteen itself.
In my case, I have a users table with id and coach_id. All users has an id (obviously) but users with role Runner has also coach_id referred to an user with role Coach.
First step is how to create the key on laravel table migration and then, how to add correct relation in User model.
First, make sure that coach_id can be NULL:
$table->unsignedInteger('coach_id')->nullable();
Use unsignedBigInteger if model id use big integers.
Then define a foreign key:
$table->foreign('coach_id')
->references('id')
->on('users')
->onDelete('set null');
Use set null instead of cascade because you don't want delete related users when coach is deleted.
And set up one-to-many relation in User model:
public function coach() {
return $this->belongsTo(self::class);
}
From Laravel > 7 you can use shortcut in migration:
$table->foreignId('coach_id')
->nullable()
->constrained('users')
->onDelete('set null');
I have a database with table Photos and table Categories. Each photo is related to one category by categoryId field.
What happens when I delete one category from Categories table? Will the photos with that category be updated with a null value in the categoryID? Or how will entity-framework react to this change?
Another question can I then reset with a mass-change the values of those categories in the photos table? And how can I do that?
hi if you have created relationship between table(using foreign key) then only the deletion of parent table will affect deletion of child table. if you just created table separately and managing relationship with your code then it will not affect the child table. if you are creating using model first approach in entity framework with specifying relation then relationship will be automatically created in backend.
their are four options available in sql on deletion of parent entity
1)No Action
2)Cascade
3)SET NULL
4)SET Default
to know how it will affect check this article
https://www.mssqltips.com/sqlservertip/2365/sql-server-foreign-key-update-and-delete-rules/
That would depend completely on how the ORM that is used defines the database model.
Assuming you use Entity Framework then you can define exactly how EF should react to that situation. In the DbContext you should find a OnModelCreating method in wich you can specify per table what restrictions you want on the table. There you can also define the behaviour of the OnDelete of a foreign key.
If you are not using EF but have your own or a different ORM then again, it depends on how that ORM is configured.
Simple check if you dont know about the used ORM is this: Does the field in the database have a foreign key and how is that configured? Also, is the field categoryID (as defined in the database) nullable? if so, then it apparently doesnt need the relation and shouldnt result in related deletes.
[user Database model][1]
https://www.linkedin.com/feed/update/urn:li:activity:6345250684744630272
here is my database design for user I want to add user_ following table in this scenario can anyone help me to build user_follower table scheme?
1- Each User has many other Users that followed him
2- Each User can follow many Users
So you have a many-to-many Unary relationship on User in your ER.
Now, to Mapping this data model to Tables: you can use a new table named: User_Followers and set 2 IDs of User as foreign key named source and target of following (and other attributes like date of follow and etc.)
you can find other mapping many-to-many Unary relationship (like Bit-Wise or Graph Data Models), but to your project, I offer as I mentioned.
I use the Zend 2 Framework to build my web application. I implemented my database table models by this tutorial: http://framework.zend.com/manual/2.1/en/user-guide/database-and-models.html
I have a many-to-many relationship between two models in my database. To get data from them I googled and found this link: http://mattmccormick.ca/2010/04/24/how-to-easily-create-models-and-table-relationships-in-zend-framework/
The problem is that all the table models extends from Zend_Db_Table_Abstract in the example. I don't know how to get data from the models.
I have a table containing votings, every voting has a unique hash id. Every voting also has tags. Therefore I defined a table tags with all the tags available and a voting_tag_map where all many-to-many relationships are mapped.
What I have tried so far is the following, that's code from my VotingTable class:
public function getTagsByVoting($votingHash){
$select = $this->tableGateway->getSql()->select();
$select->from(array('v' => 'voting'))
->join('voting_tag_map', 'v.voting_id=voting_tag_map.voting_id')
->join('tags', 'voting_tag_map.tag_id=tags.tag_id');
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet;
}
It says then:
Since this object was created with a table and/or schema in the constructor, it is read only.
Thats because of the from() method. If I delete the from() method, it says:
Statement could not be executed
Can anyone help me please?
Since this object was created with a table and/or schema in the constructor, it is read only.
This error is because you are trying to set the table name in the from clause, but it's already been set in the contructor of the TableGateway, and you can't change it once set.
If you really need to do this then you can extens AbstractTableGateway yourself then you won't have to add a string tablename to the contructor, but you don't really need to use an alias on your main table...
The SQL error you get when you comment out the from() method will be due to your referencing the votes table as it's alias 'v' in your join, when you are not using the alias v, try changing it to 'voting.XXX' from 'v.XXX'
From my understanding, cakephp doesn't support database inheritance relationship. However, I want to create a database with different type of Users.
In this case, there are three types of Users: Seller, Customer, and Administrator. Every users should have basic User information such as password, username, etc.
However, each types of users will have its own unique set of datas. For example, seller may have inventory_id while customer may have something like delivery_address, etc.
I have been thinking of creating a workaround to this problem without destroying cakephp convention. I was going to create three additional foreign keys, admin_id, seller_id and customer_id, inside User table, which links to other table. However, knowing that this is an IS-A relationship not HAS-A, I would have to make sure that two of the ids are NULL value. Therefore, this workaround seems ugly to me..
Is there any other simpler, better approach?
For this type of database structure I would probably look at adopting an Entity-Attribute-Value model. This would mean your customer may have a delivery_address and your user may have an inventory_id but as far as your relationship in Cake is concerned your both your user and customer would just have an attribute_id ... you can then create another table that stores what type of attributes are available.
It it's simplest form, your user and customer would be attached to an *attribute_lookup* or *attribute_link* table by a hasMany (probably) relationship. That attribute_lookup/link table would be connected by a belongsTo/hasOne relationship to the actual Attribute Type and Attribute Value models.
Providing that you normalise your tables correctly, you can stick well within Cake relationship conventions.
You can read more about EAV here.
I have been thinking about this problem for some time now, and I have eventually got around to build a solution for it. What I came up with is a new ORM that can be used on top of CakePHP.
It sort of works as CakePHP 3.0 with entities that represent an id/model, but it is much more advanced and supports multi table inheritance and single table inheritance.
Check it out: https://github.com/erobwen/Cream