【问题标题】:Field 'identifier' doesn't have a default value - Laravel [duplicate]字段“标识符”没有默认值 - Laravel [重复]
【发布时间】:2021-07-21 03:16:25
【问题描述】:

大家下午好!

在过去一周的某个地方,我更改了网站中的某些内容,导致以下错误:

SQLSTATE[HY000]: General error: 1364 Field 'identifier' doesn't have a default value (SQL: insert into `classifieds` (`vehicle_id`, `vehicle_type`, `updated_at`, `created_at`) values (19983, App\Models\Car, 2021-04-27 16:27:56, 2021-04-27 16:27:56))

这很奇怪,因为 $fillable 已设置(并且之前有效)。

这是正在使用的内容:

分类模型:

<?php

namespace App\Models;

use App\Http\Controllers\Controller;
use App\Rules\FileUploader;
use App\Rules\VehicleRegDate;
use Auth;
use Cache;
use CyrildeWit\EloquentViewable\Contracts\Viewable;
use CyrildeWit\EloquentViewable\InteractsWithViews;
use Eloquent;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Rennokki\QueryCache\Traits\QueryCacheable;
use ShiftOneLabs\LaravelCascadeDeletes\CascadesDeletes;
use Throwable;

/**
 * App\Models\Classified
 *
 * @property int $id
 * @property string $identifier
 * @property int|null $vehicle_id
 * @property string|null $vehicle_type
 * @property int $proprietor_id
 * @property string $proprietor_type
 * @property float $price
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @property-read Collection|Equipment[] $equipments
 * @property-read int|null $equipments_count
 * @property-read Collection|Media[] $medias
 * @property-read int|null $medias_count
 * @property-read Model|Eloquent $proprietor
 * @property-read Model|Eloquent $vehicle
 * @method static Builder|Classified newModelQuery()
 * @method static Builder|Classified newQuery()
 * @method static Builder|Classified query()
 * @method static Builder|Classified whereCreatedAt($value)
 * @method static Builder|Classified whereId($value)
 * @method static Builder|Classified whereIdentifier($value)
 * @method static Builder|Classified wherePrice($value)
 * @method static Builder|Classified whereProprietorId($value)
 * @method static Builder|Classified whereProprietorType($value)
 * @method static Builder|Classified whereUpdatedAt($value)
 * @method static Builder|Classified whereVehicleId($value)
 * @method static Builder|Classified whereVehicleType($value)
 * @mixin Eloquent
 * @property string|null $identifier_old
 * @property float $lat
 * @property float $lng
 * @property string|null $video_embed
 * @property int|null $phone
 * @property int|null $type
 * @property int $status
 * @property-read Collection|Advertising[] $adverts
 * @property-read int|null $adverts_count
 * @property-read Collection|Feature[] $features
 * @property-read int|null $features_count
 * @property-read Collection|Message[] $messages
 * @property-read int|null $messages_count
 * @property-read Collection|PriceOption[] $price_options
 * @property-read int|null $price_options_count
 * @property-read Sharing|null $sharing
 * @method static Builder|Classified whereIdentifierOld($value)
 * @method static Builder|Classified whereLat($value)
 * @method static Builder|Classified whereLng($value)
 * @method static Builder|Classified wherePhone($value)
 * @method static Builder|Classified whereStatus($value)
 * @method static Builder|Classified whereType($value)
 * @method static Builder|Classified whereVideoEmbed($value)
 */
class Classified extends Model implements Viewable
{
    use CascadesDeletes, QueryCacheable, InteractsWithViews;

    const STATUS_INACTIVE = 0;
    const STATUS_ACTIVE = 1;
    const STATUS_PENDING = 2;
    const STATUS_RETOUCH = 3;
    const STATUS_ARCHIVED = 4;
    const STATUS_REFUSED = 5;
    const STATUS_EXPIRED = 6;

    protected static $flushCacheOnUpdate = true;
    public $cacheFor = 86400;

    protected $fillable = [
        'identifier',
        'identifier_old',
        'proprietor_id',
        'proprietor_type',
        'price',
        'lat',
        'lng',
        'video_embed',
        'phone',
        'type',
        'status',
        'created_at',
        'updated_at'
    ];

    protected $hidden = [
        'id',
        'identifier_old',
        'proprietor_id',
        'proprietor_type',
        'vehicle_id',
        'vehicle_type',
        'lat',
        'lng',
        'phone',
    ];

    protected array $cascadeDeletes = ['medias', 'equipments', 'features', 'price_options', 'messages', 'adverts', 'sharing'];

    public array $rules = [
        'classified',
        'car',
        'motorcycle',
        'bike'
    ];

    public function __construct()
    {
        $this->rules['classified'] = [
            'vehicle_type' => 'required|alpha|in:car,motorcycle,bike',

            'type' => 'required|integer|exists:vehicle_data,id',

            'price' => 'required|numeric|min:1',

            'price_options.*' => 'nullable|integer|min:1',
            'features.*' => 'nullable|integer|exists:vehicle_data,id',
            'equipments.*' => 'nullable|integer|exists:vehicle_data,id',

            'fileuploader-list-files' => ['required', 'json', new FileUploader],

            'phone' => 'nullable|numeric|digits:9',
            'address' => 'nullable|string',

            'terms' => 'required|boolean',
        ];

        $this->rules['car'] = [
            'make' => 'required|integer|exists:vehicle_data,id',
            'model' => 'required|integer|exists:vehicle_data,id',
            'version' => 'nullable|string',

            'fuel' => 'required|integer|exists:vehicle_data,id',
            'firstRegDate' => ['required', new VehicleRegDate()],
            'mileage' => 'required|integer|min:0',

            'displacement' => 'required|integer|min:1',
            'power_kw' => 'nullable|integer|min:1',
            'power_hp' => 'nullable|integer|min:1',

            'bodyType' => 'required|integer|exists:vehicle_data,id',
            'bodyColour' => 'required|integer|exists:vehicle_data,id',
            'vin' => 'nullable|string|min:17|max:17',

            'annotations' => 'nullable|string',

            'transmission' => 'nullable|integer|exists:vehicle_data,id',
            'gears' => 'nullable|integer|exists:vehicle_data,id',
            'doors' => 'nullable|integer|exists:vehicle_data,id',

            'seats' => 'nullable|integer|exists:vehicle_data,id',
            'vehicle_class' => 'nullable|integer|exists:vehicle_data,id',
            'driveTrainType' => 'nullable|integer|exists:vehicle_data,id',

            'maxFuelRange' => 'nullable|numeric|min:1',
            'emission' => 'nullable|numeric|min:0.01',
            'iuc' => 'nullable|numeric|min:1',

            'particleFilter' => 'nullable|boolean',

            'warrantyDate' => 'nullable|date_format:d-m-Y',
            'warrantyKM' => 'nullable|integer|min:1',
            'inspectionDate' => 'nullable|date_format:d-m-Y',

            'registries' => 'nullable|integer|exists:vehicle_data,id',
            'origin' => 'nullable|integer|exists:vehicle_data,id',
            'license' => 'nullable|string',

            'fuelConsumptionCity' => 'nullable|numeric|min:1',
            'fuelConsumptionHighway' => 'nullable|numeric|min:1',
            'fuelConsumptionAverage' => 'nullable|numeric|min:1',

            'vintage' => 'nullable|boolean',

            'video_embed' => 'nullable|string'
        ];

        $this->rules['bike'] = [
            'framework' => 'nullable|string',
            'wheel-size' => 'nullable|numeric|min:1',
            'material' => 'nullable|string',
            'suspension' => 'nullable|string',
            'suspension-travel' => 'nullable|string',
            'shock-absorber' => 'nullable|string',
            'damping-travel' => 'nullable|string',
            'type-of-brake' => 'nullable|string',
            'brakes' => 'nullable|string',
            'speeds' => 'nullable|string',
            'gearshift-lever' => 'nullable|string',
            'rear-change' => 'nullable|string',
            'casset' => 'nullable|string',
            'chain' => 'nullable|string',
            'pedal' => 'nullable|string',
            'roses' => 'nullable|string',
            'cubes' => 'nullable|string',
            'tires' => 'nullable|string',
            'steering-gearbox' => 'nullable|string',
            'advance' => 'nullable|string',
            'guideline' => 'nullable|string',
            'fingers' => 'nullable|string',
            'saddle' => 'nullable|string',
            'seat-post' => 'nullable|string',
            'brand' => 'nullable|string',
            'warranty' => 'nullable|string',
            'hard-tail-full-suspension' => 'nullable|string',
            'year' => 'nullable|integer|min:1990|max:' . date('Y'),
            'engine' => 'nullable|string',
            'battery' => 'nullable|string',
        ];

        parent::__construct();
    }

    public function proprietor(): MorphTo
    {
        return $this->morphTo();
    }

    public function vehicle(): MorphTo
    {
        return $this->morphTo();
    }

    public function equipments(): BelongsToMany
    {
        return $this->belongsToMany(VehicleData::class, 'classified_equipment', 'classified_id', 'equipment_id');
    }

    public function features(): BelongsToMany
    {
        return $this->belongsToMany(VehicleData::class, 'classified_feature', 'classified_id', 'feature_id');
    }

    public function price_options(): BelongsToMany
    {
        return $this->belongsToMany(VehicleData::class, 'classified_price_option', 'classified_id', 'price_option_id');
    }

    public function messages(): HasMany
    {
        return $this->hasMany(Message::class);
    }

    public function adverts(): HasMany
    {
        return $this->hasMany(Advertising::class);
    }

    public function sharing(): MorphOne
    {
        return $this->morphOne(Sharing::class, 'object');
    }

    public function medias(): MorphMany
    {
        return $this->morphMany(Media::class, 'mediable');
    }

    public function getFeaturedMedia($size = null): string
    {
        try {
            if ($media = $this->medias()->orderBy('index', 'ASC')->first())
                return $media->getMediaRoute($size);

            if ($this->video_embed)
                return sprintf("https://i.ytimg.com/vi/%s/hqdefault.jpg", $this->video_embed);

            throw new Exception();

        } catch (Throwable $exception) {
            return asset_cdn('assets/img/default_listing.jpg');
        }
    }

    public function getRoute(): string
    {
        return route("classified.show", [$this->identifier, $this->getSlug()]);
    }

    public function getSlug(): string
    {
        return Str::slug($this->getTitle());
    }

    public function getTitle($size = null)
    {
        try {
            if ($this->isOtherMake() && $this->isOtherModel())
                $title = $this->vehicle->version;
            elseif ($this->isOtherMake())
                $title = $this->getModelName() . " " . $this->vehicle->version;
            else
                $title = $this->getMakeName() . " " . $this->getModelName() . " " . $this->vehicle->version;

            if ($size)
                return Str::limit($title, $size);

            return $title;

        } catch (Throwable $exception) {
            return $this->vehicle->version;
        }
    }

    public function getVehicleType(): ?string
    {
        try {
            return strtolower(explode("\\", $this->vehicle_type)[2]);

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getMakeName()
    {
        try {
            return (new Controller())->getVehicleMakeByAttr($this->getVehicleType(), $this->vehicle->make, 'id', 'value');

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getMakeNameOld()
    {
        try {
            return config('constants.' . $this->getVehicleType() . '.makes.' . $this->vehicle->make);

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getModelName()
    {
        try {
            return (new Controller())->getVehicleModelByModelAttr($this->getVehicleType(), $this->vehicle->make, $this->vehicle->model, 'id', 'value');

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getModelNameOld()
    {
        try {
            return config('constants.' . $this->getVehicleType() . '.models.' . $this->vehicle->make . '.' . $this->vehicle->model);

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getFirstRegDate()
    {
        try {
            return Carbon::parse($this->vehicle->firstRegDate);

        } catch (Throwable $exception) {
            return Carbon::parse($this->vehicle->firstRegDate);
        }
    }

    public function getFuelType()
    {
        $fuelType = Cache::get(sprintf("vehicle_data_%s_%s_%s_leaf", "classified", "fuel", $this->vehicle->fuel));

        try {
            return $fuelType->value;

        } catch (Throwable $exception) {
            return "Outro";
        }
    }

    public function getVersion($size = null)
    {
        try {
            if ($size)
                return Str::limit($this->vehicle->version, $size);
            else
                return $this->vehicle->version;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getFormattedNumber($number, $decimal = 0)
    {
        return number_format($number, $decimal, ',', ' ');
    }

    public function getBodyTypeName()
    {
        try {
            $bodyType = Cache::get(sprintf("vehicle_data_%s_%s_%s", $this->getVehicleType(), "bodyTypes", $this->vehicle->bodyType));

            return $bodyType->first()->value;

        } catch (Throwable $exception) {
            return "Outro";
        }
    }

    public function getBodyColourName() // Fix
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->bodyColour);

            return $object->value;

        } catch (Throwable $exception) {
            return "Outro";
        }
    }

    public function getTransmissionName()
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->transmission);

            return $object->value;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getGearsNumber()
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->gears);

            return $object->value;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getDoorsNumber()
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->doors);

            return $object->value;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getClassName()
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->vehicle_class);

            return $object->value;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getOriginName()
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->origin);

            return $object->value;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getLicenseFormated()
    {
        try {
            $license = strtoupper($this->vehicle->license);

            if (strlen($license) == 6) {
                $parts = str_split($license, 2);
                return implode('-', $parts);
            }

            return $license;

        } catch (Throwable $exception) {
            return "00-00-00";
        }
    }

    public function getDriveTrainTypeName()
    {
        try {
            $object = VehicleData::findOrFail($this->vehicle->driveTrainType);

            return $object->value;

        } catch (Throwable $exception) {
            return null;
        }
    }

    public function getDateFormated($date)
    {
        return Carbon::parse($date)->format('d-m-Y');
    }

    public function getDateStatus($date)
    {
        if (Carbon::parse($this->vehicle->$date) >= Carbon::today()->addDays(30))
            return "warning";
        elseif (Carbon::parse($this->vehicle->$date) < Carbon::today())
            return "danger";
        else
            return "info";
    }

    public function getVehicleTypeClassByName($name, $class = null)
    {
        switch ($name) {
            case "car":
                if (!$class)
                    return "App\Models\Car";
                else
                    return Car::class;
            case "motorcycle":
                if (!$class)
                    return "App\Models\Motorcycle";
                else
                    return Motorcycle::class;
            default:
                return null;
        }
    }

    public function getVehicleTypeByClass()
    {
        switch ($this->vehicle_type) {
            case Car::class:
                return 'car';
            case Motorcycle::class:
                return 'motorcycle';
            default:
                return null;
        }
    }

    public function getVehicleTypeNameByClass()
    {
        switch ($this->vehicle_type) {
            case Car::class:
                return 'Carro';
            case Motorcycle::class:
                return 'Moto';
            default:
                return null;
        }
    }

    public function getPhoneViews()
    {
        return 0;
    }

    public function getStatusElements()
    {
        return config('constants.status.' . $this->status);
    }

    public function getAddress()
    {
        try {
            return (new Controller())->getAddressFromGeoPosition($this->lat, $this->lng, 'city');

        } catch (Throwable $exception) {
            return "";
        }
    }

    public function getArticleCategory()
    {
        switch ($this->vehicle_type) {
            case Car::class:
                return 1;
            case Motorcycle::class:
                return 2;
            default:
                return null;
        }
    }

    public function isOtherMake(): bool
    {
        try {
            $controller = new Controller();

            if ($this->vehicle->make == $controller->getVehicleMakeOtherByVTypeAttr($this->getVehicleType(), 'slug', 'id'))
                return true;

            return false;

        } catch (Throwable $exception) {
            return false;
        }
    }

    public function isOtherModel(): bool
    {
        try {
            if ($this->vehicle->model == 0)
                return true;

            return false;

        } catch (Throwable $exception) {
            return false;
        }
    }

    public function flushCache()
    {
        try {
            Cache::forget('classified_' . $this->identifier);
            Cache::forget('medias_classified_' . $this->identifier);

            Cache::remember('classified_' . $this->identifier, 33600, function () {
                return $this;
            });

            Cache::remember('medias_classified_' . $this->identifier, 33600, function () {
                return $this->medias()->orderBy('index', 'ASC')->get();
            });

        } catch (Throwable $exception) {
        }
    }

    public function isProprietor()
    {
        try {
            if (Auth::check()) {
                if (session()->has('professional_user') && $this->proprietor_type == Branch::class && $this->proprietor_id == session()->get('professional_user'))
                    return true;
                elseif ($this->proprietor_type == User::class && $this->proprietor_id == Auth::id())
                    return true;
                elseif (Auth::user()->isAdmin())
                    return true;
            }

        } catch (Throwable $exception) {
            return false;
        }
    }

    public function getFavourites()
    {
        try {
            return $this->favourites->count();

        } catch (Throwable $exception) {
            return 0;
        }
    }

    public function isMyFavourite(): bool
    {
        try {
            $controller = new Controller();
            if ($this->favourites()->where([
                    'proprietor_id' => $controller->getProprietorId(),
                    'proprietor_type' => $controller->getProprietorType()
                ])->count() > 0)
                return true;

        } catch (Throwable $exception) {
        }

        return false;
    }

    public function favourites()
    {
        return $this->hasMany(ClassifiedFavourite::class);
    }
}

存储方法:

public function store(Request $request): JsonResponse
    {
        $rules = (new Classified)->rules;
        $request->validate($rules['classified']);
        $request->validate($rules[$request->input('vehicle_type')]);

        DB::beginTransaction();

        try {
            $vehicleData = $request->all();

            $vehicleData['firstRegDate'] = Carbon::createFromFormat('m-Y', $vehicleData['firstRegDate'])->toDateString();

            $vehicle = (new Classified())->getVehicleTypeClassByName($request->input('vehicle_type'))::create($vehicleData);

            if ($request->has('address'))
                $geoData = $this->getGeoPositionFromAddress($request->input('address'));
            else
                $geoData = (object)[
                    "lat" => 0,
                    "lng" => 0
                ];

            $formData = $request->all();
            $formData['identifier'] = $this->generateIdentifier();
            $formData['proprietor_id'] = $this->getProprietorId();
            $formData['proprietor_type'] = $this->getProprietorType();
            $formData['lat'] = $geoData->lat;
            $formData['lng'] = $geoData->lng;
            $formData['video_embed'] = $this->getYoutubeVideoID($request->input('video_embed'));
            $formData['status'] = Classified::STATUS_PENDING;

            $classified = $vehicle->classified()->create($formData);

            $vehicle->classified->price_options()->attach($request->input('price_options'));
            $vehicle->classified->features()->attach($request->input('features'));
            $vehicle->classified->equipments()->attach($request->input('equipments'));

            $medias = json_decode($request->{'fileuploader-list-files'}, true);
            foreach ($medias as $media) {
                $file = Media::where('name', $media->file)->first();
                if ($file) {
                    $file->mediable_id = $vehicle->classified->id;
                    $file->saveOrFail();
                }
            }

            if ($formData['proprietor_type'] == User::class && $request->has('phone') && $request->has('address'))
                $this->updateUserPhoneAndAddress($formData['phone'], $formData['address']);

            $classified->sharing()->create([
                'status' => Sharing::STATUS_PENDING,
            ]);

            if ($classified->status == Classified::STATUS_PENDING)
                $this->adminAlert($classified);

            DB::commit();

            toastr()->success("Anúncio submetido para aprovação.");

            return response()->json([
                'redirect_url' => route('classified.feature', $vehicle->classified->identifier),
            ]);

        } catch (Throwable $exception) {
            DB::rollBack();

            return response()->json([
                'errors' => [trans('custom.error_occurred'), $exception->getMessage()]
            ], 500);
        }
    }

堆栈错误:https://pastebin.com/jPypBG8P

有人知道这可能是什么原因吗?

【问题讨论】:

  • 这是很多代码...您最好在代码中放置一些断点以查看触发此错误的行(或检查堆栈跟踪看看它是否告诉你)。如果您正在使用源代码管理(Git 等),请查看更改并尝试找出可能导致此问题的任何内容。最后,在您的 catch (Throwable $exception) 块中添加一个 dd($exception) 以显示完整的错误;你只记录getMessage(),这不是最有用的东西。或者完全删除catch(),让你的代码错误看到一切。
  • @TimLewis 我附加了一个带有错误堆栈的粘贴箱。另外,我整个下午都检查了更改,我找不到任何可能这样做的东西(根据我所做的)。我记得将 laravel 框架从 8.35 更新到 8.38,但我也恢复了它并没有工作:(
  • 很好,虽然我在那个 PasteBin 中没有看到同样的错误。现在你有了:2021-04-27 18:38:41] production.ERROR: PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'classifieds_identifier_unique',这意味着''(空)被插入到identifier 列中。
  • @TimLewis 你知道为什么 create() 方法会丢弃数组内容吗?
  • 之后,这代表什么线? Http/Controllers/ClassifiedController.php(124):;您的堆栈跟踪表明您的错误正在发生。不,不应该; ['identifier' =&gt; ''] 更有可能在你的$formData 中(也许是通过$this-&gt;generateIdentifier()?)

标签: php laravel eloquent


【解决方案1】:

显然是分类模型中的构造函数在阻止。

特别感谢@Tim Lewis!

【讨论】:

    猜你喜欢
    • 2021-04-16
    • 2017-08-19
    • 2017-08-28
    • 2021-08-04
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2018-06-29
    相关资源
    最近更新 更多