Skip to content

Instantly share code, notes, and snippets.

@galloaleonardo
Created May 18, 2020 17:29
Show Gist options
  • Save galloaleonardo/9cb6d34ae6195f3162244470c5052bf2 to your computer and use it in GitHub Desktop.
Save galloaleonardo/9cb6d34ae6195f3162244470c5052bf2 to your computer and use it in GitHub Desktop.
<?php
namespace Your\Namespace\Traits;
use Exception;
use Illuminate\Database\Eloquent\Builder;
trait HasCompositePrimaryKey {
/**
* Get the value indicating whether the IDs are incrementing.
*
* @return bool
*/
public function getIncrementing()
{
return ! is_array($this->getKeyName());
}
/**
* Get the value of the model's primary key.
*
* @return mixed
*/
public function getKey()
{
$attributes = [];
if (is_array($this->getKeyName())) {
foreach ($this->getKeyName() as $key) {
$attributes[$key] = $this->getAttribute($key);
}
return $attributes;
}
return parent::getKey();
}
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
if (is_array($this->getKeyName())) {
foreach ($this->getKeyName() as $key) {
if (isset($this->$key)) {
$query->where($key, '=', $this->$key);
} else {
throw new Exception(__METHOD__ . 'Missing part of the primary key: ' . $key);
}
}
return $query;
}
return parent::setKeysForSaveQuery($query);
}
/**
* Execute a query for a single record by ID.
*
* @param array $ids Array of keys, like [column => value].
* @param array $columns
* @return mixed|static
*/
public static function find($ids, $columns = ['*'])
{
$me = new self;
$query = $me->newQuery();
foreach ($me->getKeyName() as $key) {
$query->where($key, '=', $ids[$key]);
}
return $query->first($columns);
}
/**
* Find a model by its primary key or throw an exception.
*
* @param mixed $ids
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public static function findOrFail($ids, $columns = ['*'])
{
$result = self::find($ids, $columns);
if ( ! is_null($result)) {
return $result;
}
throw (new ModelNotFoundException)->setModel(
__CLASS__, $ids
);
}
/**
* Reload the current model instance with fresh attributes from the database.
*
* @return $this
*/
public function refresh()
{
if (is_array($this->getKeyName())) {
if ( ! $this->exists) {
return $this;
}
$this->setRawAttributes(
static::findOrFail($this->getKey())->attributes
);
$this->load(collect($this->relations)->except('pivot')->keys()->toArray());
return $this;
}
return parent::refresh();
}
public function fresh($with = [])
{
if (is_array($this->getKeyName())) {
if ( ! $this->exists) {
return $this;
}
$query = static::newQueryWithoutScopes()
->with(is_string($with) ? func_get_args() : $with);
foreach ($this->getKeyName() as $key) {
if (isset($this->$key)) {
$query->where($key, $this->$key);
}
}
return $query->first();
}
return parent::fresh();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment