Hello everyone, I would like to ask for help in order to refute relations in the models in Laravel. I have a table of the form:

------------|------------|------------|--------------| City | Category |Subcategory | Company | ------------|------------|------------|--------------| id | id | id | id | | city_id |category_id |subcategory_id| name | name | name | name | ------------|------------|------------|--------------| 

City.php

 public function categories() { return $this->hasMany(Category::class); } 

Category.php

 public function subcategories() { return $this->hasMany(Subcategory::class); } 

Subcategory.php

 public function category() { return $this->hasMany(Company::class); } 

In general, the problem is that there are many cities and the categories may be the same for all cities, in my case, the categories are repeated for each city, yesterday I thought about it all day, tried all possible relations with Laravel and could not think out any logic. Example: If I add for example a new city and after that I want to attach categories to it and each time it turns out that I create a new and duplicate category for just 1 city ... I really hope for help ... How can I do this correctly !?

The logic is as follows: We have cities that have many companies and these companies are divided into categories and subcategories. How to zoon.ru done. Choose a city, categories appear at the bottom of the subcategory.

  • I think the problem now is that you have not quite the right notion of relations 1 to many and many to many. In fact, you have one city, and there are many companies in the city! You have one company, and it has a lot of categories .... Or are there such categories (for example, Household appliances) in one city that belong to different companies (and now there may be 10 companies that provide household appliances)? If so, then you incorrectly describe your logic - Orange_shadow
  • @Orange_shadow Categories have subcategories and companies are in subcategories already. There are not a lot of categories for companies, let's say the company “Example” is located in the city of Moscow in the category “Foo” and the subcategory “Bar”. Only here and nowhere else. In Penza in the category "Foo" and the subcategory "Bar" there is no this company. I hope correctly explained. I just don’t want the same categories and subcategories to be repeated for each city added. - pwnz22
  • one
    Well, it means that you should have hotel tables that make the connection city_category, category_company, and subcategories in general can be implemented as a category that has parent_id, unless of course one subcategory has two parents, then you will have everything in normalized form - Orange_shadow
  • @Orange_shadow I think this is the answer, you can answer in a more expanded form to select the answer as the correct one. - pwnz22

3 answers 3

What is the problem? A company has one city, one category, and possibly several subcategories.

Company:

 public function city() { return $this->belongsTo(\App\Model\City::class); } public function category() { return $this->belongsTo(\App\Model\Category::class); } public function SubCategory() { return $this->belongsToMany(\App\Model\SubCategory::class); } 

The city, in turn, has many companies.

City:

 public function company() { return $this->hasMany(\App\Model\Company::class); } 

Well, the categories and subcategories, I think, do not need jitter.

  • If I want to bring the company of one city do this: $city->company; And if I want to bring up the категории and at the bottom of the под-категории and when clicking on the под-категории bring the компании selected city , then how to do it? - pwnz22
  • Suppose in php artisan tinker I do the following Moscow: App\City::find(1)->categories->first()->subcategories->first()->companies; Peter: App\City::find(2)->categories->first()->subcategories->first()->companies; I get the same companies. - pwnz22
  • one
    Where does the city category? Companies need to choose from categories and filter by city with :: whereHas ('city_id', function ($ query) use ($ city_id) {$ query-> where ('city_id', '=', $ city_id);}) - Maxim Stepanov

It is necessary to create 2 additional tables:

1) city_category with a composite key: {city_id, category_id}, which will allow us to specify only those categories that exist in this city

2) category_company with the key: {category_id, company_id}, will allow you to link several companies with several categories

You can also abolish the Subcategory table by adding the parent_id field in the Category table, since in fact it is the same entity, but this is only if you have one category can not have multiple parents.

  • Look, let's say we have many cities and each city has its own company. If we do as you describe, it turns out 2 belongsToMany . You can connect 1 city with several categories and 1 category with several companies, but then we have the same cities in all cities. And I didn’t quite understand the account of parent_id, can you give an example? Will it belongsTo to belongsTo ? - pwnz22
  • @ pwnz22 I did not understand this phrase: "but then we have the same cities in all cities", Well, see, what difference do you have a separate table with the inscription category_id and with the same fields or just have a categories table with fields {id , title, description, parent_id}, yes the link is belongsTo - Orange_shadow
  • category_company with the key: {category_id, company_id} - If we associate companies with categories, we will have the same companies in all categories, since the categories are associated with cities, then the companies will be the same in all cities - pwnz22
  • @ pwnz22 well then you need another table :) comany_city, then you will cut in the sample only those companies that are in this city in this category - Orange_shadow
  • @ pwnz22 can of course make a triple composite key, but I'm not even sure that this is not moveton :) and the implementation of the behavior here will probably be a little more difficult - Orange_shadow
 ------------|-------------|------------|------------|--------------| City |city_category| Category |Subcategory | Company | ------------|-------------|------------|------------|--------------| id | city_id | id | id | id | | | |category_id |subcategory_id| name | category_id | name | name | name | ------------|-------------|------------|------------|--------------| 

Add a label and the belongsToMany method in the model

  • It will not work. Since several cities can not have the same company. If we make only one belongsToMany with categories it turns out that further in the subcategories there will be the same categories as in all cities and the companies are the same ... We have different companies in different cities. - pwnz22
  • By analogy category_company add .. - Andrey Svyrydov