Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Nayre пишет:То-ли вводить дополнительные поля в таблицы к существующих моделей, например в таблицу stack полей album_id, component_id и article_id (чего бы ооочень не хотелось).
очень часто денормализация базы необходима и является нормальным решением
Согласен, но пока я решил опробовать другой вариант.
Во-первых пересмотреть файловую систему в сторону ArticleId\Image.jpg - это конечно накладывает ограничение на количество папок ArticleId для линукс сисем в 31к, но до того количества проект пусть еще дорастет .
Во-вторых, попробовать избавиться от сущности Components получая сущности таким способом Albums и Texts для Articles через ->with или одтельными запросами в разные коллекции затем сливая их через merge с последующей сортировкой.
Не знаю, насколько будет рабочей схема. Попробую отписаться потом.
Версия Laravel 5.3
Версия PHP в формате 5.4
Операционная система osSiera
MySQL 5.55
Apache 2.4
В моем проекте на странице, назовем ее Articles, выводятся в заданном порядке ее child элементы.
Text - это просто текстовое поле. А вот с Album веселее, альбом может содержать произвольное количество Stack (от 1 до n) в заданном порядке. Каждый Stack может содержать произвольное количество Images (от 1 до n) в заданном порядке.
Иными словами модели:
Articles
//-----------------------------
// id | name | cover_image_id
//-----------------------------
class Articles extends Model
public function components (){
return $this->hasMany('App\Component')->orderBy('position');
}
public function image(){
return $this->belongsTo('App\Image');
}
}
0 уровень childs
Components
//-----------------------------------------
// id | article_id | type | position
//-----------------------------------------
class Component extends Model
{
public function texts (){
return $this->hasOne('App\Text');
}
public function albums (){
return $this->hasOne('App\Album');
}
}
1 уровень childs
//Texts не привожу там все просто id \| component_id | content
//Albums
//-----------------------------------------
// id | component_id | caption | description
//-----------------------------------------
class Album extends Model
{
public function stacks (){
return $this->hasMany('App\Stacks')->orderBy('position');
}
public function component()
{
return $this->hasOne('App\Component', 'id', 'component_id');
}
}
2й и 3й уровни для Albums
//Stacks
//--------------------------------------------------------------------------------------
// id | album_id | cover_image_id | caption | description | position | images_amount
//--------------------------------------------------------------------------------------
class Stacks extends Model
{
public function images (){
return $this->hasMany('App\Image')->orderBy('position');
}
public function image(){
return $this->belongsTo('App\Image');
}
}
//Images
//--------------------------------------
// id | stack_id | image_name | position
//--------------------------------------
class Image extends Model
{
public function stack()
{
return $this->hasOne('App\Stacks');
}
}
Вывод на странице осуществляется таким макаром
public function show(Article $article){
@foreach($article->components as $key => $component)
@if($component->type=='text')
<p>{{$component->texts->content}}</p>
@endif
@if($component->type=='album')
@foreach($component->albums->stacks as $stack)
@foreach($stack->images as $image)
<img data-content-type="image/jpeg" width="630" src="/content/articles/{{$article_id}}/{{$album_id}}/{{$stack->id}}/{{$image->image}}" />
@endforeach
@endforeach
@endif
@endforeach
}
В этим сложностей нет, и даже если со стороны это коряво, желаемый результат это дает.
Первые сложности возникли когда появилась необходимость получить отдельно мух без котлет - обложки cover_image для заданной article или stack на странице вывода всех статей, а так же адесов на сервере к ним. Но из этого я выкрутился добавив к первоначально нисходящим связям hasMany, восходящие hasOne. И формируя запросы таким путем
<img alt="{{$article->title}}" src="/{{'content/articles/'.$article->id.'/'.$article->image->stacks->album_id.'/'.$article->image->stack_id.'/'.$article->image->image_name}}">
Но вот когда возникла необходимость поиска среди всех stacks по названию article c выводом stacks через pagination(), я впал в ступор. Из которого пока не вышел. Так как не знаю, то-ли искать методы реализации с существующей структурой БД. То-ли начинать искать решение в новой структуре БД. То-ли вводить дополнительные поля в таблицы к существующих моделей, например в таблицу stack полей album_id, component_id и article_id (чего бы ооочень не хотелось).
Any ideas?