Как реализовать совмещение перекрестных и внутренних объединений в Laravel? - PullRequest
0 голосов
/ 23 января 2020

Я определил 3 таблицы в Laravel следующим образом:

Schema::create('locales', function (Blueprint $table) {
    $table->string('id', 2);
    $table->string('name', 5000);
    $table->timestamps();
    $table->primary('id');
});

Schema::create('i18n_keys', function (Blueprint $table) {
    $table->string('id', 255);
    $table->timestamps();
    $table->primary('id');
});

Schema::create('i18ns', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('key', 255);
    $table->string('locale', 2);
    $table->string('translation', 5000)->nullable();
    $table->timestamps();            
    $table->foreign('key')->references('id')->on('i18n_keys')->onDelete('cascade')->onUpdate('cascade');
    $table->foreign('locale')->references('id')->on('locales')->onDelete('cascade')->onUpdate('cascade');
    $table->unique(array('key', 'locale'));
});

Теперь вопрос заключается в том, как программно реализовать следующий оператор SELECT в Laravel. Я имею в виду без непосредственного выполнения оператора SQL.

SELECT `il`.`key`, `il`.`locale`, `in`.`translation` FROM 
(SELECT `ik`.`id` AS `key`, `lo`.`id` AS `locale` FROM `i18n_keys` as `ik` CROSS JOIN `locales` as `lo`) AS `il` 
left join `i18ns` as `in` 
ON `in`.`key` = `il`.`key` 
and `in`.`locale` = `il`.`locale`;

Цель состоит в том, чтобы извлечь ключи, для которых у них еще нет перевода. Но мне нравится делать это с помощью построителя запросов или eloquent или чего-то подобного, а не передавать запрос напрямую. Есть ли способ?

Result of query

1 Ответ

2 голосов
/ 23 января 2020

Вы можете попробовать этот код:

use App\Models\I18nKey;

$ik = I18nKey::crossJoin('locales as lo')
    ->select('i18n_keys.id AS key', 'lo.id AS locale');

$res = \DB::table(\DB::raw("({$ik->toSql()}) AS il"))
    ->mergeBindings($ik->getQuery())
    ->leftjoin('i18ns as in',function($join){
    $join->on('in.key', '=', 'il.key')
        ->whereColumn('in.locale', 'il.locale');
    })->select('il.key','il.locale','in.translation')->get();

...