CakePHP many to many relation with extra field - many-to-many

I have a problem with my Many to Many relation:
I have two tables related with many to many relation
Table1 (id, t1_field1, t1_field2, ...);
Table2 (id, t2_field2, t2_field2, ...);
and the association table
Table1_Table2(table1_id, table2_id, extra_field);
My problem is how to add these extra fields. I don't know how to configure the model of the two entities.
Please, can someone help me with this? Thanks

You need to change your relations. As stated in the docs, the relations transform to
Table1 hasMany Table1_Table2
Table1_Table2 belongsTo Table1, Table2
Table2 hasMany Table1_Table2
Then you need to create a model Table1_Table2 in your model folder and treat it like any other belogsTo-hasMany association, but you can add more fields (and validation if you want).

Related

Eloquent relation with father_id and mother_id in same table

I can't imagine the relationships it takes to find the best way the two following tables:
I have a table called "Poeples". It contains "ID, name and sex".
And I have an another table called "Pairs". It contains "ID, name, father_id, mother_id".
A person can belong to several pairs. And a pair can only have one parent_id and mother_id
I don't know if I need to make a foreign key for mother_id and father_id. I would like mother_id to be a poeple and father_id also a poeple (from the poeples table).
Do you have an idea of how?
I plan to use the belongsTo and hasMany relationship, but since there are two foreign keys (I do not know if that's what I have to do), I do not know how to do it.
Thank you very much
You can't make one relation for two fields.
What you need to do is to define two relations in Pair model, one would be PeopleByMother and another PeopleByFather (maybe find better naming).
Therefore a Pair model has two hasOne relations, and People has one belongsTo relation that aims for Pair model

multiple column values in mysql

I need to make a table 'Movies' which will have columns:
ID Title Description Category etc
And another one called 'Movie_Categories' containing, for example
ID Category
1 Action
2 Adventure
3 Triller
but since category in table Movies will have multiple choices what is the correct way to do this?
should i use comma-separated values like someone said in this post Multiple values in column in MySQL or is there a better way?
This is a many-to-many relationship.
You need a join table to make it right, such as :
CREATE TABLE film_category (
category_id int,
film_id int,
PRIMARY KEY (category_id, film_id)
);
DO NOT GO FOR COMMA-SEPARATED VALUES. NEVER.
Having said that. Bear in mind that when you have a so called many-to-many relationship, that is, a relationship where you can have one category with many movies and one movie with many categories, you will always need to generate an additional table.
This table will only need the Primary Keys of each of the other 2 tables and will have a compound key.
So the schema will end up being:
Movies(ID, Title, Description, Category)
Categories(ID, Category)
Movies_Categories(ID_Movie, ID_Category)
In bold are the primary keys.
In order to get all the categories for a movie you will just have to join each of the three tables.
A final comment about having multi-valued fields is that your table will not be in First Normal Form which will, sooner or later, give you lots of headaches.
The last thing to do is have a non normalized table by storing comma separated values.
*You should have a table movies and a table for categories.
You should create a mapping table which will map the movieId to the categoryId*

referencing columns of 2 different tables

Following schema:
archivebox (id, mediatype_id)
mediatype (id, name)
archivebox_records (id, archiveboxId, recordId)
picture (id,name)
print (id,name)
recordId should be referenced whether to pictureId or printId. How is it possible to solve this problem? I work with mysql.
Thanks!
It's always best to be explicit in your designs. This would involve creating two tables archive_pictures and archive_prints with foreign key relationships to the respective tables.
If you really don't want to go down that route, try adding some sort of record indicator to the archive_records table, eg
ALTER TABLE `archive_records` ADD `record_type` ENUM('picture', 'print') NOT NULL;
You can then create queries based on this indicator
SELECT p.name FROM picture p
INNER JOIN archive_records ar
ON ar.record_type = 'picture' AND p.id = ar.recordId
Another clean solution is to merge picture and print into
medium( id, name, type)
where type can be "print" or "picture" or when the datamodel grows the foreign key referencing a table containing the allowed values.

sql to populate newly created link table

I would be really grateful if somebody could help me out with this..
I actually have 2 tables in my database: books and authorlist.
The book table contains a field 'book_aut' which contains the foreign key of the authorlist table.
The authorlist table has only 2 fields, the primary key and the 'authors' column which contains a list of names.
I have to modify the table structure so that books table is linked to an authors table via a link table called 'lnk_book_author'
So my first task is to create a new table called 'authors' which contains 3 fields - primary id, name, surname, which i already did.
Next, i created the link table called 'lnk_book_author' and this one contains 3 fields, the primary id, book_fk, author_fk. The book_fk and author_fk refer to the id of the book and author respectively.
My problem is that i have more than 6000 entries in the books table and i would like to know how to populate the link table with the book id and the author id.
Is there a way of doing that using sql instead of manually populating the lnk_book_author table.
Hope i was clear enough..
Thanks a lot for any suggestion provided.
I'm infering the IDs already in your new [authors] table mean nothing with regards to the old tables. If that's the case you need to relate the records by the Name. And there I need to assume that the names are entered Identically. If they're not, it may not be possible to do. We'd need to know a lot more specifics to be sure...
INSERT INTO
lnk_book_author
SELECT
Books.PrimaryKeyFieldName,
Authors.PrimaryKeyFieldName
FROM
Books
INNER JOIN
AuthorList
ON Books.BookAut = AuthorList.PrimaryKeyFieldName
INNER JOIN
Authors
ON CONCAT(',', AuthorList.Authors, ',') LIKE CONCAT('%,', Authors.Name, ',%')
Something like that ?
INSERT INTO lnk_book_author(book_fk,author_fk)
SELECT b.book_id,a.author_id
FROM books b INNER JOIN authorlist a
ON b.book_aut=a.author_id
Try this it should work:
INSERT INTO lnk_book_author (book_fk, author_fk)
VALUES ((SELECT Id FROM books), (SELECT Id FROM authors))
And by the way there's no point having an Id column in the lnk_book_authors table, you may as well just make the foreign keys a composite primary key.
UPDATE
Sorry I realise that would only work with one record, try the following SQL:
INSERT INTO lnk_book_author (book_fk, author_fk)
SELECT books.Id, authors.Id
FROM books, authors

Merging individual tables?

I have 5 tables. table1, table2, table3, table4 and table5.
All these tables are indexed the same way, which means, for example, for name john75de, table1 contains personal details
table2 contains his skill set, table3 contains the professional experience, table4 contains the qualifications, and table5 contains additional qualifications.
These tables have been there from the beginning, but I think I need to merge all of the data into one table because these 5 tables are all referenced using the same index. There are 500k names and details in all these tables.
There are no other cross-relations between names or any data. So what do you think. Do I need to merge it? If yes, how can I do it? Since all the data relating to one name will be in a single row, I hope this will be easier. Oh, yeah, names are unique.
It sounds like a bad idea to merge these tables. A person can have multiple addresses, multiple skills, multiple previous jobs and multiple qualifications. To model this you need one to many relationships, which is best done using separate tables.
If "qualifications" and "additional qualifications" have the same structure I might be tempted to merge those two tables into a single table. To do that you can select all rows from the one table and insert them into the other, then delete the unneeded table. If you need to distinguish between the two types of qualification you can add a column for that. Here's some example SQL for copying data from one table to the other:
INSERT INTO qualifications (col1, col2, ... coln, is_additional)
SELECT col1, col2, ... coln, 1
FROM addtional_qualifications
Merging two tables can be tricky if you have an AUTO_INCREMENT PRIMARY KEY column with the same values in both tables, and other tables refer to these values via foreign key constraints.