2015-07-15 15 views
16

Mam dwie tabele, wygląda, że ​​(migracje):Get rekord ID i wszystkie foreigns rekurencyjnych w laravel 5

Schema::create('sets', function(Blueprint $table) 
{ 
    $table->increments('id'); 

    $table->string('key'); 

    $table->string('name'); 

    $table->string('set_type'); 

    $table->integer('belongs_to')->unsigned(); 

    $table->timestamps(); 

    $table->foreign('belongs_to')->references('id')->on('sets')->onDelete('cascade'); 

}); 

Schema::create('posts', function(Blueprint $table) 
{ 
    $table->bigIncrements('id'); 

    $table->bigInteger('user_id')->unsigned(); 

    $table->bigInteger('set_id')->unsigned(); 

    $table->string('post_type', 25); 

    $table->text('post'); 

    $table->boolean('is_reported')->default(false); 

    $table->boolean('is_hidden')->default(false); 

    $table->timestamps(); 

    $table->foreign('user_id')->references('id')->on('users'); 
    $table->foreign('set_id')->references('id')->on('sets'); 

}); 

„set” tabela służy do przechowywania danych, w jakiej lokalizacji (kraj, miasto ...) post powinien być widok. Na przykład, załóżmy przechowywać niektóre kraje:

id | key    | name  | belongs_to 
    1 | europe   | Europe  | null 
    2 | germany-all  | Germany  | 1 
    3 | germany-berlin | Berlin  | 2 
    4 | germany-frankfurt | Frankfurt | 2 
    5 | poland-all  | Poland  | 1 
    6 | poland-warsaw  | Warsaw  | 5 
    7 | england-all  | England  | 1 

A mój post set_id jako 6. Patrząc logicznie, kiedy chcę dostać posty z Europy (ID 1), że stanowisko powinno być zwrócone też, bo 6 należy do 5, a 5 należy do 1. I to jest to, co chcę zrobić. Można to zrobić bez używania zbyt dużej ilości PHP?

Odpowiedz

7

OK, znalazłem najlepsze rozwiązanie. To wzór zagnieżdżonego zestawu. Kiedyś baum pakiet i wygląda, że:

Dla sets tabeli I dodaje Bauma colums:

Schema::create('sets', function(Blueprint $table) { 
    $table->bigIncrements('id'); 
    $table->integer('parent_id')->nullable()->index(); 
    $table->integer('lft')->nullable()->index(); 
    $table->integer('rgt')->nullable()->index(); 
    $table->integer('depth')->nullable(); 

    $table->string('key'); 
    $table->string('name'); 
    $table->string('set_type'); 

    $table->timestamps(); 
}); 

i zrobione! Po prostu set_id i powrócić stanowisk, na przykład:

$sets = Set::where('key', '=', $myKey)->first()->getDescendantsAndSelf()->lists('id'); 
$posts = Post::whereIn('set_id', $sets)->with(['user'])->take(6)->get(); 

mam zostawić to dla potomnych;)

+1

Możesz także zrobić '$ set = Set :: where ('klucz', '=', $ myKey) -> first() -> getDescendantsAndSelf() -> list ('id');' bez używania foreach do loop, ponieważ 'getDescendantsAndSelf()' zwraca obiekt kolekcji. – blackpla9ue

+0

@ blackpla9ue Dzięki, – Siper

+0

@ blackpla9ue, idk dlaczego, ale zwraca "Call to undefined metoda Baum \ Extensions \ Eloquent \ Collection :: list()":/ – Siper

3

Musisz podzielić region, kraj i miasto na różne tabele i ustalić relacje między tymi numerami LUB możesz wyświetlić wszystkie kombinacje w jednej tabeli, np. ID | Region | Kraj | Miasto, więc masz osobny wiersz dla każdego miasta zawierającego kraj i region.

+0

mógłbym to zrobić, ale to rozwiązanie jest tylko ograniczona. Na przykład w przyszłości chcę dodać sąsiedztwo do miasta. I mam problem. Ponadto niektóre kraje mają różne podmioty, np. Stany Zjednoczone mają państwa, w Polsce mamy województwa itp. Dlatego nie mogę użyć rozwiązania, które Pan określił. – Siper

+0

@Wyjmij, jeśli podzielisz jednostki na tabele, które później łatwo będzie rozwinąć w hrabstwach, dzielnicach itp. Co więcej, nie ma znaczenia, które powiaty są wywoływane w różnych krajach, o ile są równoważne w różnych krajach. – L4zl0w