Каков наилучший способ запросить некоторые данные у модели или контроллера непосредственно из представления в Laravel?

#php #laravel #eloquent #laravel-blade #laravel-7

#php #laravel #красноречивый #laravel-blade #laravel-7

Вопрос:

У меня есть 2 таблицы: Продукты и изображения.

У каждого продукта есть много изображений (через внешний ключ product_id)

 *product_id, product_title*
1, "Product 1"
2, "Product 2"
3, "Product 3"
4, "Product 4"
  
 *image_id, product_id(foreign key), image_url, created_at*
25,  1,  "/filename_xyz", '5:00'
26,  1,  "/filename_abc", '5:30'
27,  2,  "/filename_def", '6:30'
28,  1,  "/filename_abc", '7:00'
29,  3,  "/filename_def", '8:00'
  

У меня есть контроллер, который возвращает все продукты в мое представление.

ProductController.php

 public function index(){
        $data_to_return = Product::orderby('product_id', 'DESC')->paginate(10);

        return view('product.index', [
            'product_data' => $data_to_return,
        ]);
    }
  

Этот контроллер загружается в view корректно product.index.

Я успешно перебираю результаты в моем блейд-файле следующим образом:

 @foreach($product_data as $product)
{{ $product->product_title }}
<!--however, I would like to also print one of the images linked to a product-->
@endforeach
  

У меня возникли проблемы с планированием «ссылки» или «присоединения» к изображению. Для продукта с product_id=1 в базе данных изображений имеется несколько записей. Я хотел бы, чтобы мое представление отображало информацию о продукте из таблицы Products, а также ТОЛЬКО ОДНО изображение из таблицы Images (соответствующее product_id). В моем случае мне нужен первый результат (или ограничение 1) при заказе с помощью created_at ASC.

Пример: Продукт 1 отобразил бы в моем представлении image_url «/filename_xyz», потому что он был создан первым из изображений с product_id = 1

Я думал, что решение может быть примерно таким:

Зациклите массив продуктов:

 @foreach($product_data as $product)
{{ $product->product_title }}

<!-- And calling a controller like -->

{{Image::mainImage($product->id)}}

<!-- Where mainImage returns the image_url I am looking for-->
@endforeach
  

или

Улучшаю свою модель, сначала определенным образом соединяю таблицы, что делает то, о чем я упоминал ранее, показывая только одно изображение, которое меня интересует. Я не могу понять, как добиться этого с помощью наилучшей практики Laravel / Eloquent.

Комментарии:

1. {{ $product->image_url[0] }}

Ответ №1:

Вот где пригодились бы красноречивые взаимосвязи!

Взаимосвязь ваших моделей должна напоминать эту настройку;

 class Product extends Model
{
    public function image()
    {
        return $this->hasOne('your/path/to/image/model');
    }
}

class ProductImage extends Model
{
    public function product()
    {
        return $this->belongsTo('your/path/to/product/model');
    }
}
  

И при правильной настройке вы бы сделали что-то вроде <img src="{{ $product->image->image_url }}"> для отображения изображения продукта. Это предполагает, что у вас есть только одно изображение для каждого продукта.

При ваших миграциях, скажем, при вашей product_images миграции таблиц, вы должны написать $table->foreignId('product_id')->constrained(); , и Laravel автоматически узнает, где искать соответствующую запись изображения.

Комментарии:

1. Спасибо за объяснение! Как бы вы подошли к проблеме, когда у вас есть несколько изображений, связанных с одним и тем же product_id, но возвращающих только первую найденную строку изображения, а не остальные изображения (изображение будет: order by ‘created_at’ ASC LIMIT 1).

2. Если у вас их более одного product_image на product строку, то я бы обновил приведенную выше взаимосвязь Product с hasOne на hasMany , и вы могли бы вызвать $product->images::first() . Я полагаю, что именно так это и будет работать, я еще не тестировал это, имейте в виду, но это должно быть приблизительной идеей