Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

abkrim's avatar
Level 13

Strange behavior in a resource: Column not found

My model

Campaign

protected $guarded = [];

Nova/Campaign

public function fields(Request $request)
{
    return [
...
       Boolean::make('DNS burcode', 'own_dns')->rules('required'),

}

Update form and get error

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'own_dns' inf 'field list' (SQL: update users set own_dns = 1, users.updated_at = 2021-12-24... wher id= 128

But when show update form value is correct and show in form.

https://imgur.com/a/rBi6UJ0

Any ideas?

0 likes
13 replies
Tray2's avatar

Check your users table, it does not have a column named own_dns

abkrim's avatar
Level 13

@Tray2 My resource has not use model User,. Models is Campaign, and that is the problem.

Update resource tries UPDATE a wrong table/model.

Not users, not User in nova resource.

Why Nova tries run a sql to users table?

abkrim's avatar
Level 13

@Tray2 My resource has not use model User,. Models is Campaign, and that is the problem.

Update resource tries UPDATE a wrong table/model.

Not users, not User y nova resource.

Why Nova tries run a sql to users table?

abkrim's avatar
Level 13

Double check in table. Table has a column own_dns and form on nova show perfectly true or false if value in column is true or false.

Sinnbeck's avatar

@abkrim so can you run this query in your database manager?

update users set own_dns = 1, users.updated_at = 2021-12-24... wher id= 128 
abkrim's avatar
Level 13

@Sinnbeck Now i see error.

On my resource there are not anything for users table and message show SQL:update users and table of resource is not users is 'campaigns`

https://imgur.com/a/EMyH787

I don't understand why Resource create a sql update action for table users, if campaign model has not any relation with users table.

<?php

namespace App\Nova;

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;

class Campaign extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = \App\Models\Campaign::class;

    /**
     * The single value that should be used to represent the resource when being displayed.
     *
     * @var string
     */
    public static $title = 'campaign';

    /**
     * The columns that should be searched.
     *
     * @var array
     */
    public static $search = [
        'id', 'campaign', 'web'
    ];

    public static $group = 'Mailer';

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make(__('ID'), 'id')->sortable(),

            Text::make('Campaña', 'campaign')
                ->sortable()
                ->rules(
                    'required',
                    'max:100',
                    'min:5',
                    Rule::unique('campaigns')->ignore($this->id),
                ),

            Text::make('Db', 'db')->rules('required', 'max:64', 'min:5')->hideFromIndex(),

            Text::make('Web', 'web')->rules('max:254')->hideFromIndex(),

            Text::make('Cp User', 'cpuser')->rules('required', 'min:3', 'max:8')->hideFromIndex(),

            Boolean::make('DNS burcode', 'own_dns')->trueValue(1)->falseValue(0)->rules('required'),

            Text::make('Tabla', 'table')->rules('required','max:64')->hideFromIndex(),

            Text::make('Email', 'email_from')->rules('required', 'max:264')->hideFromIndex(),

            Text::make('Nombre Emisor', 'name_from')->rules('max:264')->hideFromIndex(),

            Text::make('Identificador', 'identifier')
                ->rules(
                    'size:8',
                    function ($attribute, $value, $fail) {
                        if (! preg_match('/^[A-Z0-9]{8}$/', $value)) {
                            $fail('Identificador debe tener 8 digitos en mayusculas y números solamente');
                        }
                    },
                    Rule::unique('campaigns')->ignore($this->id),
                )->hideFromIndex(),

            Select::make('Mailer', 'mailer')->options([
                1 => 'Sendgrid',
                2 => 'Smtp',
                3 => 'Mailtrap'
            ])->default(1)->displayUsingLabels(),

            Text::make('Estado', function ($model) {
                return  \App\Models\Campaign::STATUS_SELECT[$model->status];
            })->exceptOnForms(),
        ];
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function filters(Request $request)
    {
        return [];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function lenses(Request $request)
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function actions(Request $request)
    {
        return [];
    }
}

I've cleared all...

❯ a:clear
Compiled services and packages files removed!
Configuration cache cleared!
Application cache cleared!
Compiled views cleared!
Route cache cleared!
Generating optimized autoload files
Class ParsedownExtraTest located in ./vendor/erusev/parsedown-extra/test/ParsedownExtraTest.php does not comply with psr-0 autoloading standard. Skipping.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: 64robots/nova-fields
Discovered Package: abkrim/sendgrid
Discovered Package: abkrim/whmapi
Discovered Package: armincms/json
Discovered Package: barryvdh/laravel-ide-helper
Discovered Package: binarytorch/larecipe
Discovered Package: david-griffiths/nova-dark-theme
Discovered Package: facade/ignition
Discovered Package: fruitcake/laravel-cors
Discovered Package: gregoriohc/laravel-nova-theme-responsive
Discovered Package: laravel/dusk
Discovered Package: laravel/horizon
Discovered Package: laravel/nova
Discovered Package: laravel/sail
Discovered Package: laravel/sanctum
Discovered Package: laravel/tinker
Discovered Package: laravel/ui
Discovered Package: livewire/livewire
Discovered Package: melihovv/laravel-package-generator
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Discovered Package: spatie/laravel-database-mail-templates
Discovered Package: spatie/laravel-ray
Discovered Package: stechstudio/laravel-ssh-tunnel
Package manifest generated successfully.
Generated optimized autoload files containing 7704 classes
Sinnbeck's avatar

So is there an own_dns column in the database?

abkrim's avatar
Level 13

@Sinnbeck Yes is not users table.

That is the error.

Resource has models Campaing, and de model has table Campaigns.

And tables or models User && Campaign has any relationship.

If I click on **Update & Continue Editing" on my resource, sql must be a SQL for update table campaigns and column own_dns .

Error show that Nova tires update a table users .... Why?

Models campaing

<?php

namespace App\Models;

use App\Values\CampaignExtra;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Campaign extends Model
{
    use HasFactory;

    public const STATUS_SELECT = [
        1 => 'Pendiente', // Without status (initial)
        2 => 'Configurada', // Tiene registros cpanel y sendgrid
        3 => 'Activa', // Sending campaign
        4 => 'Finalizada', // End sending
        5 => 'Archivada',
        6 => 'Pendiente DNS', //  Pending external DNS for verification
    ];

    public const MAILER_SELECT = [
        1 => 'Sendgrid',
        2 => 'Smtp',
        3 => 'Mailtrap'
    ];

    public $table = 'campaigns';

    protected $dates = [
        'start_in',
        'end_at',
        'datetime_events',
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    protected $guarded = [];

//    protected $fillable = [
//        'campaign',
//        'db',
//        'table',
//        'cpuser',
//        'own_dns',
//        'email_from',
//        'name_from',
//        'identifier',
//        'extra',
//        'datetime_event',
//        'start_in',
//        'end_at',
//        'status',
//        'mailer',
//        'extra->organizer_name',
//        'extra->organizer_address',
//        'extra->organizer_zipcode',
//        'extra->organizer_city',
//        'extra->organizer_phone',
//        'extra->organizer_person',
//        'external'
//    ];

    protected $casts = [
        'start_in' => 'datetime:Y-m-d H:i:s',
        'end_at' => 'datetime:Y-m-d H:i:s',
        'datetime_event' => 'datetime:Y-m-d H:i:s',
        'extra' => CampaignExtra::class,
        //'external' =>
    ];

    public function getStatusColorAttribute()
    {
        return [
            1 => 'yellow',
            2 => 'indigo',
            3 => 'pink',
            4 => 'green',
            5 => 'gray'
        ][$this->status];
    }

    public function getStartInForHumansAttribute()
    {
        return is_null($this->start_in)
            ? ''
            : $this->start_in->format('M, d Y');
    }

    public function getStartInForEditingAttribute()
    {
        return $this->start_in->format('Y-m-d H:i:s');
    }

    public function getDateTimeEventForHumansAttribute()
    {
        return is_null($this->datetime_event)
            ? ''
            : $this->datetime_event->format('M, d Y H:i:s');
    }

    public function getDateTimeEventForEditingAttribute()
    {
        return $this->datetime_event->format('Y-m-d H:i:s');
    }

    public function getEndAtForHumansAttribute()
    {
        return is_null($this->end_at)
            ? ''
            : $this->end_at->format('M, d Y');
    }

    public function getEndAtForEditingAttribute()
    {
        return $this->end_at->format('Y-m-d H:i:s');
    }

    public function getStatusLabelAttribute($value)
    {
        return static::STATUS_SELECT[$this->status] ?? null;
    }

    public function getExternalObjectAttribute()
    {
        return is_null($this->external)
            ? ''
            : json_decode($this->external);
        //return json_decode($this->external);
    }

    public function subscribers(): BelongsToMany
    {
        return $this->belongsToMany(Subscriber::class); //->using(CampaignSubscriber::class);
    }

    public function templates(): HasMany
    {
        return $this->hasMany(Template::class);
    }
}
abkrim's avatar
Level 13

Incredible..

If comment a Field named 'table' that usually for all records is users (some times in other name) work fine,

// Text::make('Tabla', 'table')->rules('required','max:64')->hideFromIndex(),

So I interpret that there is a bug, in which when there is that Field with value users, Nova changes the direction of the update and generates TWO sql.

One that updates the correct model, Campaing, and another that tries to update the users table ....

abkrim's avatar
Level 13

I create a migration for rename column table to spanish tabla

Modify resource and work fine.

abkrim's avatar
Level 13

Solution in Github

Problem is use public $table in model Campaign instead protected $table

A terrible mistake.

Please or to participate in this conversation.