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

ElpsySec's avatar

Polymorphic Relationships with Custom Column Names

I am working with a large database that I can't edit easily so I'm trying to work with what I have.

I have a product that has a locationId and locationType. The locationId can refer to either a WebStore or LocalStore model. Currently, the locationType id is either "WEB" for WebStore or "LOCAL" for LocalStore. Is there any way to establish a polymorphic relationship with these custom column names and values?

More Detailed:

I have a Product Table:

$table->increments('id');
$table->string('name');
$table->integer('locationId')->unsigned();
$table->string('locationType');

A WebStore Table:

$table->increments('id');
$table->string('name');

A LocalStore Table:

$table->increments('id');
$table->string('name');

My Models would look something like Product Model

    public function locationId()
    {
        return $this->morphTo();
    }

WebStore Model:

 public function Product()
 {
  return $this->morphOne('App\Models\Product', 'locationId');
  }

LocalStore Model:

 public function Product()
 {
  return $this->morphOne('App\Models\Product', 'locationId');
  }

Is there a way to specify that:

  1. locationId is the key we're looking for

  2. locationType is the type we're looking for

  3. The location type "WEB" refers to App\Models\WebStore and "LOCAL" refers to LocalStore

Thanks

If this is not possible, any advice on how to establish this relationship would help. Adding an additional column like locationIdType that holds the class name is a possibility. If this could work, could you elaborate on how to specify that locationId would be the locationId. Does what I have now work if I were to do that.

0 likes
3 replies
ElpsySec's avatar
ElpsySec
OP
Best Answer
Level 5

For posterity, a kind soul names Thomas answered my question on stack overflow: http://stackoverflow.com/questions/34073999/laravel-polymorphic-relationship-trouble-with-camel-case

General answer: If you aren't going to follow the standard naming structure, the morphOne method accepts additional parameters that allow you to override it.

public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
{
    $instance = new $related;

    list($type, $id) = $this->getMorphs($name, $type, $id);

    $table = $instance->getTable();

    $localKey = $localKey ?: $this->getKeyName();

    return new MorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
}

Without knowing your database structure, all I can tell you is that the 4th argument allows you to override the id. That's where you put locationId.

2 likes

Please or to participate in this conversation.