Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hailwood/57668d2a079833330f4dad2bdb4435ad to your computer and use it in GitHub Desktop.
Save hailwood/57668d2a079833330f4dad2bdb4435ad to your computer and use it in GitHub Desktop.
Laravel custom relationship
<?php
namespace App\Eloquent\Concerns;
use Illuminate\Support\Str;
use App\Eloquent\Relationships\LeaveableMorphToMany;
/**
* Trait HasCustomRelationships
*
* @mixin \Eloquent
*/
trait HasCustomRelationships
{
/**
* Define a polymorphic, inverse many-to-many relationship (leaveable).
*
* @param string $related
* @param string $name
* @param string $table
* @param string $foreignPivotKey
* @param string $relatedPivotKey
* @param string $parentKey
* @param string $relatedKey
*
* @return \App\Eloquent\Relationships\LeaveableMorphToMany
*/
public function leaveableMorphedByMany($related, $name, $table = null, $foreignPivotKey = null,
$relatedPivotKey = null, $parentKey = null, $relatedKey = null)
{
$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
// For the inverse of the polymorphic many-to-many relations, we will change
// the way we determine the foreign and other keys, as it is the opposite
// of the morph-to-many method since we're figuring out these inverses.
$relatedPivotKey = $relatedPivotKey ?: $name . '_id';
return $this->leaveableMorphToMany(
$related, $name, $table, $foreignPivotKey,
$relatedPivotKey, $parentKey, $relatedKey, true
);
}
/**
* Define a polymorphic many-to-many relationship (leaveable).
*
* @param string $related
* @param string $name
* @param string $table
* @param string $foreignPivotKey
* @param string $relatedPivotKey
* @param string $parentKey
* @param string $relatedKey
* @param bool $inverse
*
* @return \App\Eloquent\Relationships\LeaveableMorphToMany
*/
public function leaveableMorphToMany($related, $name, $table = null, $foreignPivotKey = null,
$relatedPivotKey = null, $parentKey = null,
$relatedKey = null, $inverse = false)
{
$caller = $this->guessBelongsToManyRelation();
// First, we will need to determine the foreign key and "other key" for the
// relationship. Once we have determined the keys we will make the query
// instances, as well as the relationship instances we need for these.
$instance = $this->newRelatedInstance($related);
$foreignPivotKey = $foreignPivotKey ?: $name . '_id';
$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
// Now we're ready to create a new query builder for this related model and
// the relationship instances for this relation. This relations will set
// appropriate query constraints then entirely manages the hydrations.
if (!$table) {
$words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
$lastWord = array_pop($words);
$table = implode('', $words) . Str::plural($lastWord);
}
return new LeaveableMorphToMany($instance->newQuery(), $this, $name, $table,
$foreignPivotKey, $relatedPivotKey, $parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(), $caller, $inverse);
}
}
<?php
namespace App\Eloquent\Relationships;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
class LeaveableMorphToMany extends MorphToMany
{
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Eloquent\Concerns\HasCustomRelationships;
class Stable extends Model
{
use HasCustomRelationships;
public function wrestlers()
{
return $this->leaveableMorphedByMany(Wrestler::class, 'member')->withPivot('left_at');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Eloquent\Concerns\HasCustomRelationships;
class Wrestler extends Model
{
use HasCustomRelationships;
public function stables()
{
return $this->leaveableMorphToMany(Stable::class, 'member');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment