Получить запись по ID и всем иностранцам, рекурсивным в 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" предназначена для хранения данных, в которых местоположение (страна, город...) должно быть просмотрено. Например, позвольте хранить некоторые страны:

   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

И мой пост имеет set_id как 6. Глядя логически, когда я хочу получать сообщения из Европы (ID 1), этот пост тоже должен быть возвращен, потому что 6 принадлежит 5, а 5 принадлежит 1. И это то, что Что я хочу сделать. Можно ли обойтись без использования слишком большого количества PHP?

Ответы

Ответ 1

Хорошо, я нашел лучшее решение. Это шаблон вложенного набора. Я использовал baum и выглядит так:

В таблице sets я добавил столбцы Баума:

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();
});

И сделано! Просто получите сообщения set_id и return, например:

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

Я оставляю это для потомков;)

Ответ 2

Вам нужно разбить регион, страну и город на разные таблицы и установить связь между этими OR вы можете перечислить все комбинации в одной таблице, то есть ID | Регион | Страна | Город, чтобы у вас была отдельная строка для каждого города, содержащего страну и регион.