【问题标题】:SQLSTATE[42S22]: Column not found: 1054 Unknown column 'items.box_box_barcode' in 'where clause'SQLSTATE [42S22]:未找到列:1054 'where 子句'中的未知列'items.box_box_barcode'
【发布时间】:2020-06-08 03:41:45
【问题描述】:

我正在尝试显示来自 2 个数据库表(boxesitems)的数据,这些表在 Laravel 5.8 中具有 2 个具有一对多关系的模型。当我尝试在视图中显示数据时,出现以下错误:

SQLSTATE[42S22]:找不到列:1054 'where 子句'中的未知列 'items.box_box_barcode'(SQL:从 `items` 中选择 *,其中 `items`.`box_box_barcode` = TRTB0001 和 `items`。` box_box_barcode` 不为空)

查看我的代码:

Box.php(模型)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Box extends Model
{

    protected $guarded = [];


    protected $primaryKey = 'box_barcode';
    public $incrementing = false;
    protected $keyType = 'string';



    public function items(){

        return $this->hasMany(Item::class);
    }
}

Item.php(模型)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Item extends Model
{

    protected $primaryKey = 'item_barcode'; // or null

    public $incrementing = false;

    // In Laravel 6.0+ make sure to also set $keyType
    protected $keyType = 'string';


    public function company(){

        return $this->belongsTo(Company::class);
    }
}

create_boxes_table.php(迁移 1)

<?php

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

class CreateBoxesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('boxes', function (Blueprint $table) {
            //$table->bigIncrements('id');
            $table->string('box_barcode')->primary();
;      //want this to be my id that can increment
            $table->string('sort_description');
            $table->timestamps();
        });
    }

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

create_items_table.php(迁移 2)

<?php

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

class CreateItemsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            //$table->bigIncrements('id');
            $table->string('item_barcode')->primary();
; //want this to be my id that can increment
            $table->string('its_box_barcode');
            $table->string('item_quality');
            $table->timestamps();


        });
    }

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

boxesController.php(控制器)

<?php

namespace App\Http\Controllers;

use App\Box;
use Illuminate\Http\Request;

class boxesController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $boxes = Box::all();       
        return view('boxes.index', compact('boxes'));
    }


    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Box  $box
     * @return \Illuminate\Http\Response
     */
    public function show(Box $box)
    {
        return view('boxes.show', compact('box'));
    }


}

index.blade.php(视图)

@extends('layout')


@section('title', 'Boxes')  


@section('content')


    <h1>Boxes</h1>

     <ul style="list-style-type: none;">

       @foreach($boxes as $box) 

         <li>
            <a href="/boxes/{{ $box->box_barcode }}">
                {{$box->box_barcode}}  
            </a>
         </li>

       @endforeach

    </ul>           

 @endsection

show.blade.php(查看)

@extends('layout')


@section('title', 'Show Box')  


@section('content')


@if ($box->items->count())
    <div>
        @foreach ($box->items as $item)

            <div>

                <form method="POST" action="/items/{{ $item->id }}">
                    @method('PATCH')
                    @csrf

                    <!-- USE TO STRIKETHROUGH A CONPLETED TASK IN WEB PAGE -->
                    <label class="checkbox {{ $item->in ? 'is-complete' : '' }}" for="in" >

                    <input type="checkbox" name="in" onChange="this.form.submit()" {{ $item->in ? 'checked' : '' }}>
                            {{ $item->item_barcode }}

                    </label>


                </form>



            </div>

        @endforeach

    </div>
@endif

@endsection

【问题讨论】:

  • 你有 its_box_barcode 和 box_barcode 但没有 box_box_barcode !?
  • 嗨,B.Go。你的意思是? box_barcode 是 box 表的 PK。 item_barcode 是项目表的 PK。我不想查看 its_box_barcode

标签: php mysql laravel eloquent


【解决方案1】:

通过为列使用奇怪的名称,您会失去很多 Laravel 通常自动执行的功能。但正如the documentation 中所述,您可以“通过向 hasMany 方法传递额外的参数来覆盖外键和本地键。”

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Box extends Model {
    protected $guarded = [];
    protected $primaryKey = 'box_barcode';
    public $incrementing = false;
    protected $keyType = 'string';

    public function items() {
        return $this->hasMany(Item::class, 'its_box_barcode', 'box_barcode');
    }
}

您还需要定义项目和盒子之间的反向关系,同样使用您的非标准列名。

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Item extends Model {

    protected $primaryKey = 'item_barcode'; // or null
    public $incrementing = false;
    protected $keyType = 'string';


    public function box() {
        return $this->belongsTo(Box::class, 'its_box_barcode', 'box_barcode');
    }
}

建议您坚持使用框架的预期命名约定,这样可以省去很多麻烦。即boxes.box_barcode应该是boxes.barcodeitems.item_barcode应该是items.barcode,而items.its_box_barcode应该是items.box_id,指向一个名为id的标准数字键列。是的,如果您已经在数据库中拥有另一个独特的值,这有点浪费,但如果您不这样做,您将违反惯例。所以我建议的模型代码会很简单:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Box extends Model {
    public function items() {
        return $this->hasMany(Item::class);
    }
}

class Item extends Model {
    public function box() {
        return $this->belongsTo(Box::class);
    }
}

您还应该在迁移中使用 foreign key constraints 在数据库级别定义这些关系:

Schema::create('boxes', function (Blueprint $table) {
    $table->bigIncrements('id')->primary();
    $table->string('barcode');
    $table->string('sort_description');
    $table->timestamps();
});

Schema::create('items', function (Blueprint $table) {
    $table->bigIncrements('id')->primary();
    $table->string('box_id');
    $table->string('barcode');
    $table->string('quality');
    $table->timestamps();
    $table->foreign('box_id')->references('id')->on('boxes')->onDelete('cascade');
});

现在,您可以在模板中引用如下内容:

@foreach ($boxes as $box)
    {{ $box->barcode }} 
    @foreach ($box->items as $item)
        {{ $item->barcode }}
    @endforeach
@endforeach

【讨论】:

  • 谢谢米肯,这行得通。这在很大程度上是我的好奇心。我是 laravel 的新手,我不希望好奇心害死猫,所以我会坚持 id 命名约定和 fk 约束
  • 我更新了答案以详细说明标准设置的外观。
猜你喜欢
  • 2020-03-01
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 2023-04-07
  • 2019-08-18
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多