This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

KurtJensen
KurtJensen

I struggled for hours with this until I found this:

http://stackoverflow.com/a/28164707/2410693

WaskiWabit
WaskiWabit

Defining the following in a model

protected $primaryKey = array('key1', 'key2');

Produces a string to array error. Apparently $primaryKey does not support arrays when using the RelationController in conjunction.

Last updated

chris10207
chris10207

Did you find any better solution for this ?

sukarsa27391
sukarsa27391

I found this for laravel, https://github.com/mopo922/LaravelTreats/blob/master/src/Model/Traits/HasCompositePrimaryKey.php Then I adapt it to OctoberCMS below:
The KeyName is a string concatenation of composite keys.
The KeyValue is a string of values, separated by '-'.
This makes it compatible with the octobercms / ajax and templating.

On your model class, you must use:

     class YourClass extends Model
     {  
         use \YourName\YourApp\Traits\HasCompositePrimaryKeys;
         protected $primaryKey = ['first_key','second_key'];
         ...

This is the source code, save it to a file named "plugins/YourName/YourApp/Traits/HasCompositePrimaryKey.php

 <?php namespace  YourName\YourApp\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 false;
}

/**
 * Get the primary key for the model.
 * The keyName string is concatenation of primaryKey using '_', with '_' at start
 *
 * @return string
 */
public function getKeyName()
{
    return '_'.implode('_', $this->primaryKey);
}

/**
 * Get the value of the model'ames primary key.
 * The attribute value is '-' separated values. 
 * Attribute array is also set when this is called, so the key name will be properly replaced by the widget template.
 * @return mixed
 */
public function getKey()
{
    $attributes = [];
    foreach ($this->primaryKey as $key) {
        $attributes[] = $this->getAttribute($key);
    }
    $value = implode('-',$attributes);
    $this->setAttribute($this->getKeyName(),$value);
    //return implode('-',$attributes); 
    return $value;
}

/**
 * Set the keys for a save update query.
 *
 * @param  \Illuminate\Database\Eloquent\Builder $query
 * @return \Illuminate\Database\Eloquent\Builder
 */
protected function setKeysForSaveQuery(Builder $query)
{
    foreach ($this->primaryKey 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;
}
/**
 * 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($composite_id, $columns = ['*'])
{
    $ids = explode('-',$composite_id);
    $me = new self;
    $query = $me->newQuery();
    foreach ($me->primaryKey as $index => $key) {
        $query->where($key, '=', $ids[$index]);
    }
    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($composite_id, $columns = ['*'])
{

    $result = self::find($composite_id, $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 (!$this->exists) {
        return $this;
    }
    $this->setRawAttributes(
        static::findOrFail($this->getKey())->attributes
    );
    $this->load(collect($this->relations)->except('pivot')->keys()->toArray());
    return $this;
}
}

Last updated

1-4 of 4

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.