Relacje w larawerze

0

Dzień dobry, mam pewien problem, chciałem zrobić jedno poziomowe menu i przypisywać do odpowiednich subkategorii i kategorii produkty, celem optymalizacji i nauki, chcę mieć możliwość wypisywania wszystkiego jednym zapytaniem czyli:
Categoria1
Subcategoria1
produkt1
produkt2
produkt3
Categoria2
Subcategoria1
produkt4
produkt5
Subcategoria3
produkt6

Teraz nieco opiszę w jaki sposób zrobiłem tabele i relacje
Category i subcategory jest many to many (category_subcategory) a w tabeli produkt odwołuje się do tabeli category_subcategory i mam relację do niego w polu category_subcategory_id.

category
id
name

subcategory
id
name

category_subcategory
id
category_id
subcategory_id

item
id
name
category_subcategory_id.

Teraz nieco kodu w jaki sposób wykonuję relacje w modelach.

class Subcategory extends Model
{
    protected $fillable = [
        'id',
        'name',
    ];

    protected $table = 'subcategories';


    public function categories()
    {
        return $this->belongsToMany(CategoriesTwoLevel::class, 'categories_subcategories', 'subcategories_id','categories_id');
    }
}


class Categories extends Model
{
    protected $fillable = [
        'id',
        'name',
    ];

    protected $table = 'categories';

    protected $timestamp = false;

    public function subcategory()
    {
        return $this->belongsToMany(Subcategory::class, 'categories_subcategories', 'categories_id', 'subcategories_id')->withPivot('id');
    }

}

Za pomocą tego zapytania wyciągam odpowiednio dane z tabel category i subcategory

CategoriesTwoLevel::with('subcategory')->get();

Problem jest taki że nie widzę możliwość odwołania się do tabeli item poprzez to zapytanie, być może jest coś nie tak z relacjami i powinny być wykonane inaczej, mimo najszczerszych chęci utknąłem.

0

nooo musisz utworzyć relacje do item

0
mr_jaro napisał(a):

nooo musisz utworzyć relacje do item

Właśnie i tutaj mam blokadę bo zupełnie nie widzę możliwosci.

0

Zacznijmy od tego, że "celem optymalizacji i nauki, chcę mieć możliwość wypisywania wszystkiego jednym zapytaniem" jest niewykonalne jesli robisz do eloquentem a z tego co widzę robisz eloquentem, w tej instrukcji co napisałeś laravel zrobi 3-4 zapytania :)

0

A jaki jest najoptymalniejszy i możliwie najprostszy sposób na wykonanie tego? query builder ?

0

i dochodzimy do tego co w optymalizacji najciekawsze, to, że masz 4 zapytania nie znaczy, że beda wolniejsze od jednego zapytania :) Taki mysql włąsnie woli wiele małych zapytań zamiast jednego ciężkiego ALE tez nie jest tak w każdym przypadku :) Przechodząc do sedna, rób w eloquencie ale mniej na uwadze, że to, że to co w nim napisałeś to nie oznacza, że pod spodem wygeneruje też tylko tyle zapytań.

Co do samego problemu... jak nikt nie pomoże to jutro mogę przemyśleć problem i powiedzieć jak ja bym to zrobił, dziś nie chce mi się myśleć, tylko powiedz jeszcze ten "item to czym właściwie jest?

0

Jeszcze będe dzisiaj nad tym myślał.
Item to tabela z produktami, jeden produkt może należeć tylko do jednej kategorii i subkategorii (razem).

0

czyli kategoria -> subkategoria -> item ? No to dodaj relacje w subkategorii i wtedy


$categories = CategoriesTwoLevel::with('subcategory.item')->get();

$item = $categories[0]->subcategory[0]->item;
0
mr_jaro napisał(a):

czyli kategoria -> subkategoria -> item ? No to dodaj relacje w subkategorii i wtedy


$categories = CategoriesTwoLevel::with('subcategory.item')->get();

$item = $categories[0]->subcategory[0]->item;

zmienie relację i dam znać jak poszło.

0

Obawiam się że to nie przejdzie, subcategoria nie ma żadnego powiązania w bazie z produktem.
Bardziaj pasowało by takie zwizualizowanie tego

(Category->Subcategory)->item

gdzie to co jest w nawiasie to tabela trzymająca relację między Kategoriami a subcategoriami.

0

Nie wiem czy to jest odpowiednie wyjście, ale wymyśliłem takie coś że będe sprawdzał ifem czy pole w tabeli Items gdzie trzymana jest relacja do ID pola w tabeli category_subcategory, czy podany if się zgadza z tym z tabeli Items, jeśli tak to wypisuje te produkty.

0

Jak nie ma jak, :) relacja nigdy nie jest jednostronna, jeśli x ma wiele y to y ma jeden x

0

Zdaje sobie z tego sprawę, tylko widzisz ani Category ani Subcategory nie mają relacji z tabelą Item, z tą tabelą ma relacje category_subcategory czyli musiałbym operować na Modelu Category_Subcategory, chyba że jest jakaś możliwość aby mimo to odwołać się z tabeli Subcategory do tabeli Item, w tabeli subcategory jest tylko id oraz nazwa subcategorii, w tabeli category jest id i nazwa categorii głównej.

1

można zastosować pivota, ale w sumie źle zaprojektowałeś tabelki, po co ci ta tabelka category_subcategory? Ja bym to zrobił tak i by był ten sam efekt.

category
id
name

subcategory
id
category_id
name

item
id
subcategory_id
name

0
mr_jaro napisał(a):

można zastosować pivota, ale w sumie źle zaprojektowałeś tabelki, po co ci ta tabelka category_subcategory? Ja bym to zrobił tak i by był ten sam efekt.

category
id
name

subcategory
id
category_id
name

item
id
subcategory_id
name

To ma sens, zabieram się kodowania.

0

No ok, a co w przypadku jak chciałbym dodać tę samą subcategorie do dwóch osobnych kategorii głównych? wtedy nazwy subcategorii będą się powialały. Można oczywiście wykonać distinct na tej tabeli, ale czy to rozwiązuje problem ?

0

ale po co? czemu chcesz mieć tę samą podkategorie w kilku kategoriach? to się mija z celem troche np są 2 kategorie buty i bluzki, do obu dodajesz podkategorie męśkie, damskie i teraz przypiszesz jakieś buty do męskich ALE butów a nie męskich wpiętych i do butów i do bluzek, bo jaki to by miało sens?

0
mr_jaro napisał(a):

ale po co? czemu chcesz mieć tę samą podkategorie w kilku kategoriach? to się mija z celem troche np są 2 kategorie buty i bluzki, do obu dodajesz podkategorie męśkie, damskie i teraz przypiszesz jakieś buty do męskich ALE butów a nie męskich wpiętych i do butów i do bluzek, bo jaki to by miało sens?

Po zaimplementowaniu wszystko działa jak należy. Poprzednio miałem taki problem, że subcategorie dublowały się jak chciałem przypisać ją do kategorii

0

Może po prostu wyciągnij wszystkie itemy?

$items = Item::query()->join('cs')->join('c')->join('s');

Gdzie c to category, sto subcategory, acs to ta Twoja tabela łącznikowa.

0
TomRiddle napisał(a):

Może po prostu wyciągnij wszystkie itemy?

$items = Item::query()->join('cs')->join('c')->join('s');

Gdzie c to category, sto subcategory, acs to ta Twoja tabela łącznikowa.

Tak, takie coś działało, ale jest to nieco niespójne, wypisuje kategorie wyciągając dane z modelu Item, tutaj coś Mi nie pasuje, nie jest to za bardzo czytelne. Chętnie dowiem się czy wypisywanie kategorii bazująć na modelu item przeszłoby review.

0

@Brunatny Kot
Przecież chcesz wyciągnąć przedmioty, razem z kategoriami. Nie było mowy o samych tylko kategoriach.

0

Zacznijmy od tego, że Twój design bazy jest do kitu.
Powinno być tak:

categories
  id int
  parent_id int + nullable
  name string

products
  id int
  category_id int
  name string

Dzięki temu nie potrzebujesz już aż trzech tabel do opisu samych kategorii + możesz mieć zagłębienia dowolnej wielkości w drzewie kategorii.

Potem wszystko możesz pobrać zapytaniem Product::with('category')->get() i otrzymasz pięknie dwa zapytania (nie licząc pobrania związku category.parent, która może wymagać trzeciego, jeśli będziesz też chciał to mieć, przy czym sprytnie można to też zrobić za pomocą dwóch).

0

Czytałem o tym sposobie i będe się uczył go stosować.

0

Swoją drogą, znajdę gdzieś w jaki sposób wykonać w za pomocą eloquenta ?

0

O którym sposobie mówisz?

0

Dokładnie o tym

categories
  id int
  parent_id int + nullable
  name string

products
  id int
  category_id int
  name string
0

W sensie co konkretnie chcesz przeczytać?
Jak zaprojektować taką bazę, jak wykonywać na niej zapytania czy co?

0

Nie chcę iść na łatwiznę, spróbuję samodzielnie, a jak nie będzie wychodziło to będę pisał w tym temacie aby nie robić następnego.

1

Ogólnie rzecz biorąc, szukaj informacji pod kątem mysql hierarchical structure / mysql tree structure (tudzież laravel tree structure).

1 użytkowników online, w tym zalogowanych: 0, gości: 1