laraveleloquent

Why relation with morph table raised error?


Having a morph table in laravel 10 app :

    public function up(): void
    {
        Schema::create('locations', function (Blueprint $table) {
            $table->id();

            $table->morphs('model');

            $table->string('place', 100)->nullable();
            $table->decimal('lng', 8,4);
            $table->decimal('lat', 8,4);

            $table->index(['model_type', 'model_id', 'place']);

From Branch model I need relation OneToOne and in app/Models/Branch.php :

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Branch extends Model
{

    protected $table = 'branches';
    protected $primaryKey = 'id';
    public $timestamps = true;

...

    public function location()
    {
//        public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
        return $this->morphOne(related: 'App\Models\Location', name: 'branchable', id: 'id', localKey: 'model_id');
    }

and in app/Models/Location.php :

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;

class Location extends Model
{
    protected $table = 'locations';
    protected $primaryKey = 'id';
    public $timestamps = false;

    protected $fillable = [ 'place', 'lng', 'lat' ];

    public function branchable(): MorphTo
    {
//        public function morphTo($name = null, $type = null, $id = null, $ownerKey = null)
        return $this->morphTo(name: 'place', type: 'App\Models\Branch', id:'id', ownerKey: 'model_id');
    }
}

but whe in brances request I try to read also

with('location')

Got error :

 Column not found: 1054 Unknown column 'locations.branchable_type' in 'where clause'
SELECT
*
FROM
`locations`
WHERE
`locations`.`id` IN (?)
AND `locations`.`branchable_type` = App \ Models \ Branch

What is wrong in my relations


Solution

  • The issue is the name you are providing.

    return $this->morphOne(related: 'App\Models\Location', name: 'branchable', id: 'id', localKey: 'model_id');
    

    Laravel uses the name and appends _type and _id to determine the morph columns. So in your case, you need to provide name as model so that Laravel will use the model_type and model_id columns.

    So it should be

    public function location(): MorphOne
    {
        return $this->morphOne(Location::class, 'model');
    }