通过'id'或'name'抓取厂商标志并显示在table - Laravel 8 - aJax

Grab manufacturer logo by 'id' or 'name' and display in table - Laravel 8 - aJax

大家早上好。

我创建了一个车辆数据库,其中包含一些详细信息,例如发动机类型、燃料、变速器、制造商等等...

我首先为每个条目选择徽标,但很快意识到我最终会得到一个文件夹,里面装满了相同的徽标,只是时间戳不同而已。

因此,我尝试创建一个手动将所有制造商徽标上传到资产文件夹的过程,然后当我输入 'Manufacturer Name' 时,它将使用该信息从 public/storage/assets 中提取相关徽标.

我的车型

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Vehicle extends Model
{
    use HasFactory; /**  Name of columns fillable */
    protected $table = 'vehicles';
    protected $fillable = [
        'make',
        'model_name',
        'version',
        'powertrain',
        'trans',
        'fuel',
        'model_year',
        'image',
        'created_at'

    ];
};

我的车辆控制器

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\Vehicle;
use Illuminate\Http\Controllers;
use Illuminate\Database\Migrations\CreateVehiclesTable;

class VehiclesController extends Controller
{
    public function index()
    {
        return view('index');
    }

    /** Handle insert */

    public function store(Request $request)
    {
        // print_r($_POST);
        // print_r($_FILES);
        // // }


        $file = $request->file('image');
        $filename = time(). '.' .$file->getClientOriginalExtension();
        $file->storeAs('public/images', $filename);



        // handle insert vehicle ajax request
        $vehicle = Vehicle::create(
            [
            'make' => $request->make,
            'model_name' => $request->model_name,
            'version' => $request->version,
            'powertrain' => $request->powertrain,
            'trans' => $request->trans,
            'fuel' => $request->fuel,
            'model_year' => $request->model_year,
            'image' => $filename
            ]
        );

        return response()->json($vehicle);
    }

    // FETCH ALL AJAX REQUEST

    public function fetchAll()
    {
        $vehicles = Vehicle::all(); //Could be model or controller...
        $output = '';
        if ($vehicles->count() > 0) {
            $output .= '<table class="table table-striped table-sm text-center align-middle" >
                <thead>
                    <tr>
                        <th class="tbl-head">ID</th>
                        <th class="tbl-head">Image</th>
                        <th class="tbl-head">Make</th>
                        <th class="tbl-head">Model</th>
                        <th class="tbl-head">Derivative</th>
                        <th class="tbl-head">Powertrain</th>
                        <th class="tbl-head">Transmission</th>
                        <th class="tbl-head">Fuel Type</th>
                        <th class="tbl-head">Model Year</th>
                    </tr>
                </thead>
                <tbody>';
            foreach ($vehicles as $vehicle) {
                $output .= '<tr class="tbl exp_tbl">
                    <td>'.$vehicle->id.'</td>
                    <td><img src="./storage/images/'.$vehicle->image.'"  class="img-thumbnail justify-content-sm-center rounded-circle"></td>
                    <td>'.$vehicle->make.'</td>
                    <td>'.$vehicle->model_name.'</td>
                    <td>'.$vehicle->version.'</td>
                    <td>'.$vehicle->powertrain.'</td>
                    <td>'.$vehicle->trans.'</td>
                    <td>'.$vehicle->fuel.'</td>
                    <td>'.$vehicle->model_year.'</td>
                    <td>
                        <a href="#" id="'.$vehicle->id.'" class="text-success mx-2 editIcon" data-bs-toggle="modal" data-bs-target="editVehicleModal"><i class="bi-pencil-square h4"></i></a>

                        <a href="#" id="'.$vehicle->id.'" class="text-danger mx-1 delete-icon"><i class-"bi-trash h4"></i></a>
                    </td>
                </tr>';
            }
            $output .= '</tbody></table>';
            echo $output;
        } else {
            echo '<h1 class="text-center text-secondary my-5">No vehicles in the database!</h1>';
        }
    }

    public function time($time)
    {
        $time->Carbon::now();
    }
}

我的迁移文件

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateManufacturersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('manufacturers', function (Blueprint $table) {
            $table->id('id');
            $table->string('manu_logo');
            $table->string('manu_name');
            $table->timestamps('created_at');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('manufacturers');
    }
}

我的印象是我需要生成一个新模型并使用当前的 VehiclesController 从制造商模型中提取徽标。

我想我有点困惑,希望得到任何帮助,如果需要更多信息,请随时询问

提前致谢

有几种解决方法:

a) 使用制造商 id 获取徽标;

b) 使用制造商名称提供标识,但这种情况下每次都需要加载制造商关系;

c) 在创建 Vehicle 模型时使用 image 字段提供基于制造商的徽标 url (在其他变体中,您不需要 image 字段 Vehicle型号可用于提供车辆照片而不是制造商标志);

d) creating/updating Manufacturer 使用时上传标志(根据你的制造商 table 迁移 - 这是你想要的).

所以

a) 步骤:

  1. 将一堆徽标上传到 public/logo 与汽车相关的文件夹 制造商 id 如 1.png、2.png 等任何你想要的方式(手动或带有上传请求的某种形式)
  2. 在您的 Vehicle 模型中创建 getter 以获得徽标 url
  3. 在第 2 步中创建的控制器中使用 getter 以提供相关徽标的显示
// Vehicle Model
public function getLogoUrlAttribute() {
  $path = "logo/$this->make.png";
  return Storage::exists($path) ? Storage::url($path) : '';
}

// controller fetchAll() method
...
  <td><img src="$vehicle->logo_url"  class="img-thumbnail justify-content-sm-center rounded-circle"></td>
...


b) 步骤:

  1. 将一堆徽标上传到 public/logo 与汽车相关的文件夹 制造商 name 如 wv.png、audi.png 等任何你想要的方式(手动或带有上传请求的某种形式)
  2. 在您的 Vehicle 模型中创建 getter 以获得徽标 url
  3. 在第 2 步中创建的控制器中使用 getter 以提供相关徽标的显示
// Vehicle Model
public function getLogoUrlAttribute() {
  if (!$this->relationLoaded('manufacturer') {
    return '';
  }
  $name = $this->manufacturer-> manu_name;
  $path = "logo/$name.png";
  return Storage::exists($path) ? Storage::url($path) : '';
}

// controller fetchAll() method
...
  <td><img src="$vehicle->logo_url"  class="img-thumbnail justify-content-sm-center rounded-circle"></td>
...


c) 步骤:

  1. 将一堆徽标上传到 public/logo 与汽车相关的文件夹 制造商 id 如 1.png、2.png 等任何你想要的方式(手动或带有上传请求的某种形式)
  2. 在创建新的 vihecle 时将徽标的路径设置为 image 字段
// store() method
/* you don't need this anymore 
$file = $request->file('image');
$filename = time(). '.' .$file->getClientOriginalExtension();
$file->storeAs('public/images', $filename);*/
  $path = Storage::exists('logo/$request->make.png') ?  "logo/$request->make.png" : '';
  $vehicle = Vehicle::create(
     [
       'make' => $request->make,
       'model_name' => $request->model_name,
       'version' => $request->version,
       'powertrain' => $request->powertrain,
       'trans' => $request->trans,
       'fuel' => $request->fuel,
       'model_year' => $request->model_year,
       'image' => $path
     ]
  );

// fetchAll() method
...
<td><img src="Storage::url($vehicle->image)"  class="img-thumbnail justify-content-sm-center rounded-circle"></td>
...

使它变得更好

//Vehicle model
public function getLogoUrlAttribute() {
  return Storage::url($this->image);
}

// fetchAll() method
...
<td><img src="$vehicle->logo_url" class="img-thumbnail justify-content-sm-center rounded-circle"></td>
...

d) 步骤:

  1. 在创建 Manufacturer 时上传其徽标(用任何你想要的名称保存它,因为它会被路径绑定)
  2. 从预加载的 manufacturer 关系中获取徽标 url
// ManufacturerController
public function store() {
  // create new manufacturer and store provided logo image
}

// Vehicle model
public function manufacturer() {
  return $this->hasOne(Manufacturer::class, 'make', 'id');
}

// Manufacturer model
public function getLogoUrlAttribute() {
  return Storage::url("logs/$this->manu_logo.png");
}

// vehicle controller
public function fetchAll() {
  // note preloading manufacturer relation
  $vehicles = Vehicle::with('manufacturer')->get();
...
  <td><img src="" . $vehicle->manufacturer->logo_url class="img-thumbnail justify-content-sm-center rounded-circle"></td>
...
}

为了确保避免 n+1 请求问题,我建议仍然在 Vehicle 模型中使用 getter 作为徽标

// adding to Vehicle model
public function getLogoUrlAttribute() {
  if (!$this->relationLoaded('manufacturer') {
    return '';
  }
  $name = $this->manufacturer->manu_logo;
  $path = "logo/$name.png";
  return Storage::exists($path) ? Storage::url($path) : '';
}
// fetchAll() method
...
  <td><img src="$vehicle->logo_url" class="img-thumbnail justify-content-sm-center rounded-circle"></td>
...


关于您的 fetchAll() 方法的一些想法: 我建议您让 blade 为您构建页面 - 这将使控制器变得漂亮和清晰

public function fetchAll() {
  // note preloading manufacturer relation
  $vehicles = Vehicle::with('manufacturer')->get();
  return view('vehicle-index', ['$vehicles'=>$vehicles]);
}

vehicle-index.blade.php 中的所有 html 东西,使用起来更愉快

<html lang="{{ app()->getLocale() }}">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <meta name="Cache-Control" content="no-cache, no-store, must-revalidate" />
  <meta name="Pragma" content="no-cache" />
  <meta name="Expires" content="0" />

  <title>title</title>

  <!-- CSRF Token -->
  <meta name="csrf-token" content="{{ csrf_token() }}">
</head>

<body>
  @if ($vehicles->isEmpty())
  <h1 class="text-center text-secondary my-5">No vehicles in the database!</h1>
  @else
  <table class="table table-striped table-sm text-center align-middle">
    <thead>
      <tr>
        <th class="tbl-head">ID</th>
        <th class="tbl-head">Image</th>
        <th class="tbl-head">Make</th>
        <th class="tbl-head">Model</th>
        <th class="tbl-head">Derivative</th>
        <th class="tbl-head">Powertrain</th>
        <th class="tbl-head">Transmission</th>
        <th class="tbl-head">Fuel Type</th>
        <th class="tbl-head">Model Year</th>
      </tr>
    </thead>
    <tbody>
      <tr class="tbl exp_tbl">
        <td>{{ $vehicle->id }}</td>
        <td><img src="{{ $vehicle->logo_url }}" class="img-thumbnail justify-content-sm-center rounded-circle"></td>
        <td>{{ $vehicle->make }}</td>
        <td>{{ $vehicle->model_name }}</td>
        <td>{{ $vehicle->version }}</td>
        <td>{{ $vehicle->powertrain }}</td>
        <td>{{ $vehicle->trans }}</td>
        <td>{{ $vehicle->fuel }}</td>
        <td>{{ $vehicle->model_year }}</td>
        <td>
          <a href="#" id="{{ $vehicle->id }}" class="text-success mx-2 editIcon" data-bs-toggle="modal" data-bs-target="editVehicleModal"><i class="bi-pencil-square h4"></i></a>

          <a href="#" id="{{ $vehicle->id }}" class="text-danger mx-1 delete-icon"><i class="bi-trash h4"></i></a>
        </td>
      </tr>
    </tbody>
  </table>
  @endif

</body>