I have the following Models and relationships.
AppSubscriber.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateSupportFacadesDB;
use IlluminateSupportStr;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use GrosvLaravelPasswordlessLoginTraitsPasswordlessLogin;
class Subscriber extends Authenticatable
{
use Notifiable, PasswordlessLogin;
public function customFieldValues()
{
return $this->morphMany(CustomFieldValue::class, 'customFieldValueable');
}
}
AppCustomField.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use AppModelsCampaign;
class CustomField extends Model
{
protected $fillable = [
'name',
'key',
'type',
'field_options'
];
public function customFieldValues()
{
return $this->hasMany(CustomFieldValue::class);
}
}
AppCustomFieldValues.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class CustomFieldValue extends Model
{
use HasFactory;
protected $fillable = ['custom_field_id', 'value', 'custom_field_valueable_id', 'custom_field_valueable_type'];
public function customField()
{
return $this->belongsTo(CustomField::class);
}
public function customFieldValueable()
{
// If you are using custom column names, specify them here. Otherwise, ensure they match the migration.
return $this->morphTo(null, 'custom_field_valueable_type', 'custom_field_valueable_id');
}
}
AppCampaign.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use AppModelsCustomField;
class Campaign extends Model
{
protected $dates = [
'imported_at'
];
protected $casts = [
'imported_at' => 'datetime',
'exported_at' => 'datetime'
];
protected $fillable = [
'uuid',
'name',
'slug',
'client_id'
];
public function customFieldValues()
{
return $this->morphMany(CustomFieldValue::class, 'customFieldValueable');
}
}
AppNewsletter.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Newsletter extends Model
{
protected $fillable = [
'uuid',
'name',
'brand_id',
'active',
'create_send_list_id',
'last_imported'
];
public function brand()
{
return $this->belongsTo(Brand::class);
}
public function subscribers()
{
return $this
->belongsToMany(Subscriber::class)
->withPivot('active')
->withTimestamps();
}
public function customFieldValues()
{
return $this->morphMany(CustomFieldValue::class, 'customFieldValueable');
}
}
My migration to create the table to support this looks like this,
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('custom_field_values', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('custom_field_id');
$table->string('value');
// Manually create the polymorphic columns
$table->unsignedBigInteger('custom_field_valueable_id');
$table->string('custom_field_valueable_type');
// Manually specify a shorter index name
$table->index(['custom_field_valueable_type', 'custom_field_valueable_id'], 'custom_field_valueable_index');
$table->timestamps();
$table->foreign('custom_field_id')->references('id')->on('custom_fields')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('custom_field_values');
}
};
However in the Nova interface when I try and view a subscriber I get the following error,
SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘custom_field_values.customFieldValueable_type’ in ‘where clause’ (Connection: mysql, SQL: select * from
custom_field_values
wherecustom_field_values
.customFieldValueable_type
= AppModelsSubscriber andcustom_field_values
.customFieldValueable_id
= 1016 andcustom_field_values
.customFieldValueable_id
is not null order bycustom_field_values
.id
desc limit 6 offset 0)
If someone could explain to me where I have gone wrong that would great. I am very new to polymorphic relationships.
2
Answers
the laravel query is looking for a column customFieldValueable_type but you have a custom_field_valueable_type in your db.
The error seems to be coming from the
AppCustomFieldValues.php
specifically in the function:The correct naming conventions can be found here in the laravel docs.
The conventions should be:
If you want to use the standard naming convention:
And then change the db columns name accordingly
try like this: