У меня есть таблица cms_contents
, которая содержит контент для всех участников (посмотрите на них как на пользователей) и всех локалей.Эта таблица содержит содержимое по умолчанию для каждой локали, но можно переопределить это содержимое по умолчанию для каждого экспонента и запросить их собственную версию на основе поля name
.
Пример минималистической таблицы
| id | exhibitor_id | name | locale | content |
| --- | ------------ | -------------- | ------ | --------------------------- |
| 1 | NULL | privacy-policy | en | Default Privacy Policy ... |
| 2 | NULL | privacy-policy | nl | Standaard privacybeleid ... |
| 3 | 1 | privacy-policy | en | Custom Privacy Policy... |
Я хочу создать функцию для запроса одной или нескольких записей и возвращать только правильное содержимое, следуя этим правилам, в этом порядке, останавливаясь при первом совпадении 1. Для этого name
и этого * имеется специальное содержимое (совпадения экспонента)1009 * 2. Для этого name
и этого locale
3 имеется содержимое по умолчанию (экспонент_ пусто). 3. Для этого name
есть содержимое по умолчанию (экспонент_идуль равно нулю), и locale
соответствует резервному языку 4.Остальные комбинации на самом деле не имеют значения, это значит, что я неправильно ввел данные в БД.
Вот что у меня есть сейчас.
class CmsContent extends Model {
/**
* Returns a query builder with for fetching CmsContent with default content
*
* @param null $exhibitor_id
*
* @return static
*/
public static function withDefaultContent($exhibitor_id = null)
{
if (is_null($exhibitor_id)) {
$exhibitor_id = exhibitor()->id;
}
//TODO remove the need for database to not be in strict mode
return static
::where(function (Builder $query) {
return $query
->where('locale', app()->getLocale())
->orWhere('locale', config('app.fallback_locale'));
})
->where(function (Builder $query) use ($exhibitor_id) {
return $query
->where('exhibitor_id', $exhibitor_id)
->orWhereNull('exhibitor_id');
})
->orderByRaw('FIELD(`locale`, ?, ?)', [app()->getLocale(), config('app.fallback_locale')])
->orderBy('exhibitor_id', 'desc')
->groupBy(['name']);
}
}
Пример использования
CmsContent::withDefaultContent()->where('name', 'privacy-policy')->first()
Проблема с этой функцией заключается в том, что GROUP BY не учитывает ORDER BY.Когда я удаляю GROUP BY, элементы сортируются правильно, если GROUP BY будет принимать первый результат каждой группы.Но это не так.
Вторая проблема заключается в том, что MySQL не должен находиться в строгом режиме.
Как я могу красноречиво подойти к этому вопросу?