I have two Models one is Offer (for offers table) and other is Brand (for brands table). There is a "many to many" relationship between these models.
I have a table offer_brands that maps the relation between these two tables. In this table, I have offer_id column that links this table to offers table and brand column that links this table to the brands table usind brand_name column in brands table.
In Brand Model I want a relation that return all the offers.
I know I can do it like
public function offers()
{
return $this->belongsToMany(Offer::class, 'offer_brands', 'offer_id', 'brand_id'); // But don't have brand_id column insted I have brand column that contains brand names
}
Also, I have tried
public function offers()
{
return $this->belongsToMany(Offer::class, 'offer_brands', 'offer_id', 'brand'); // But Eloquent compare this column with id column of brands table.
}
Just in case if someone still looking for an answer .. here's how you can solve this issue.
For example I have roles for users. and the pivot table (team_users) has the user_id. But instead of containing the role_id it contains role column which basically is the slug of the role in roles table.
I can specify the relation exactly like this:
public function roles()
{
return $this->belongsToMany('App\Role', 'team_users', 'user_id', 'role', 'id', 'slug');
}
Basically App\Role is the relation model.
team_users is the pivot table name.
user_id is the foreign pivot key (So in team_users there will be a column called user_id)
role is the related pivot key (So in team_users there will be a column called role)
id is the parent key (So in App\User Laravel will look for the row whose id column value equals the foreign pivot key user_id in the pivot table).
slug is the related key (So in App\Role Laravel will look for the row whose slug column value equals role column in the pivot table)
The correct definition:
return $this->belongsToMany(Offer::class, 'offer_brands', 'brand', 'offer_id');
But it's a good idea to use naming conventions. You could name the table brand_offer and foreign keys as offer_id and brand_id. In this case, the relationship would look like this:
return $this->belongsToMany(Offer::class);
Learn more about Laravel naming conventions in my best practices repo.
Related
I want to insert a new row in a table (user) with a many-to-many relation to an other table (tag). The user does not exist prior to this operation. The tag must be inserted only if not present in the tag table. The relation table is always populated as a user must have at least one tag.
The User entity has a primary generated column id, some columns, and this many-to-many relation:
#ManyToMany(
type => Tag,
tag => tag.users,
{ cascade: true }
)
#JoinTable(
{ name: "user_tags" }
)
tags!: Tag[]
The Tag entity has a primary generated column id, a name column, and a similar many-to-many relation to Users entity like the one above. The tables are created and the relation table is also there.
+---------+---------+-------------------------+
| user_tags |
+---------+---------+-------------------------+
| userId | int(11) | PRIMARY KEY FOREIGN KEY |
| tagId | int(11) | PRIMARY KEY FOREIGN KEY |
+---------+---------+-------------------------+
I want to use createQueryBuilder like the docs suggests:
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post)
.add(category)
The problem is that I don't know what post or category refers to.
Source says .of()
Sets entity (target) which relations will be updated.
And that .add()
Adds (binds) given value to entity relation. Value can be entity, entity id or entity id map (if entity has composite ids). Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids). Works only for many-to-many and one-to-many relations. For many-to-one and one-to-one use #set method instead.
Can someone explain this to me as I don't understand how to use it? Also maybe a commented code example of the whole process?
Thank you.
I'm a newbie in database design.
Can anybody look at this design:
Initially I created these tables - m2m relation first. It was simple:
students
contacts
contact_types
But new table teachers was added into database after that.
...and each teacher may have contact too.
I just added new column into contacts "junction" table.
But I don't like this design, because there are empty values in columns of teacher_id and student_id columns.
Is there better way to create many-to-many relations for that situation?
Main goal is to get ability of adding multiple contacts for one student/teacher.
The former variant of my design, but I don't know if it is optimal or not.
To allow your design to be M:M you need something like this:
table teacher { id, .... }
table student { id, ...}
table contact { id, typeId, value }
table contactType {id, ....}
table contact_teacher {contactId, teacherId}
table contact_student {contactId, studentId}
Then you have your M:M relationship between student and contact and teacher and contact
The right way to create a many to many relationship between teachers and contacts is to create a "joining table" that table would look like this:
contactteacher table
name type
id int - auto increment
teacherid int
contactid int
I like to call the tables by the things they join ordered alphabetically that is why I suggest the name contactteacher
There might be additional information for contact -- like where you met someone or when you met them.
There could also be meta data in the table -- when the record was created when it was edited, who created it -- etc.
Let’s assume there are some rows in a table cars, and each of these rows has an owner. If this owner were always a person (conveniently situated in a table persons), this would be your standard one-to-many relation.
However, what if the owner could not only be a person, but also a company (in a table companies)? How would this relationship be modeled and how would it be handled in PHP?
My first idea was to create a column person and a column company and check that one of them always stays NULL, while the other is filled – however, that seems somewhat inelegant and becomes impractical once there is a higher number of possible related tables.
My current assumption would be to not simply create the foreign key as an integer column person in the table, but to create a further table called tables, which gives IDs to the tables, and then split the foreign key into two integer columns: owner_table, containing the ID of the table (e.g. 0 for persons and 1 for companies), and owner_id, containing the owner ID.
Is this a viable and practical solution or is there some standard design pattern regarding such issues? Is there a name for this type of problem? And are there any PHP frameworks supporting such relations?
EDIT: Found a solution: Such structures are called polymorphic relations, and Laravel supports them.
There are multiple ways to do it.
You can go with two nullable foreign keys: one referencing company and the other user. Then you can have a check constraint which assure you one is null. With PostgreSQL:
CREATE TABLE car{
<your car fields>
company_id INT REFERENCES car,
person_id INT REFERENCES person,
CHECK(company_id IS NULL AND person_id IS NOT NULL
OR company_id IS NOT NULL AND person_id IS NULL)
};
Or you can use table inheritance (beware their limitations)
CREATE TABLE car_owner{
car_owner_id SERIAL
};
CREATE TABLE company{
<company fields>
} INHERITS(car_owner);
CREATE TABLE person{
<person fields>
} INHERITS(car_owner);
CREATE TABLE car{
<car fields>
car_owner_id INT REFERENCES car_owner
};
I'm creating a database of bookshelf.
I have a table named BookInfo which contains information regarding book title , category and many other properties related to it.
I have different table named category which have categoryID and categoryName with it.
Problem : I want to insert multiple category for single book information.waht would be the feasible solution.
The solution is normalize your DB.
Is not correct if you have more Category tables. You must use one Category table, then to link it to your BookInfo table you must create a middle table, for example, named, CategoryBook, where your middle table must be these fields:
ID (your PK table)
field PK BookInfo (as FK)
field PK Category (as FK)
Alternatively, your middle table can be built as follow:
PK BookInfo (as FK)
PK Category (as FK)
where two upper field are the PK of your table
You can create a mapping table as "Book_Category" which will have
BookID, CategoryID and if you want create a composite primary key for "Book_Category" table by combining both the columns.
You must have one more table to handle it.
OR
You have to add into BookInfo table only.
OR
Category column should hold different categoryID's
I am new to DB design and I am having some trouble finding info on how to define a "Many to One" relationship. I can find all sorts of info on "One to Many" and "Many to Many" but nothing on "Many to One". My hangup is how to store the data. What I have is one table called "Categories" then I have another table called "Inventory", each "Inventory" item can belong to multiple "Categories".
How do I store multiple "Categories" in a single "Inventory" row? Should I have a intermediate table that stores the "Categories" ID with the corresponding "Inventory" ID? Or would adding something like a JSON string that has the "Categories" ID's in the "Inventory" row be the right way to do this? Or is there a way to store an Array of "Categories" ID's in the "Inventory" row?
Thanks allot for the help!
the correct term of Many to One is One to Many. simply create a table like this,
CREATE TABLE Categories
(
CategoryID INT Primary KEY,
CategoryName
);
CREATE TABLE InventoryList
(
ProductID INT Primary KEY,
CategoryID INT,
ProductName VARCHAR(50),
CONSTRAINT tb_fk FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID)
);
First I would suggest that you download mysql workbench - it gives you a nice visual db design mode so you can see how things hang together (creates foreign key relationships etc etc for you).
In this instance this is actually a many-to-many relationship. as such you will need a category table, an inventory table and a category_has_inventory table (or inventory_has_category depending on semantics) where you store the id of the inventory and category in each tuple - workbench even creates this table for you when using the many-to-many relationship tool.
Pop back on here if you need further help.
IF a category can only contain one inventory item then you could create a one-to many relationship by adding inventory_id to the category table but that sounds wrong to me.
"Many to one" is just "One to many" looked at from the other end.
Just add a column inventory_id to the Categories table.
If not only each "Inventory" item can belong to multiple "Categories" but also each "Categories" item can belong to multiple "Inventory" items, than you have a many-to-many relation for which you need a intermediate table with category_id and inventory_id.