2

I've structured my Record as such:

<?php
namespace Craft;

class MyPlugin_MerchantOrderRecord extends BaseRecord
{
  public function getTableName()
  {
    return 'myplugin_merchant_orders';
  }

  protected function defineAttributes()
  {
    return [
      'merchant_id' => AttributeType::Number,
      'order_id' => AttributeType::Number,
      ...
    ];
  }

  public function primaryKey()
  {
    return ['merchant_id', 'order_id'];
  }

  public function defineRelations()
  {
      return [
        'merchant' => [static::BELONGS_TO, 'MyPlugin_MerchantRecord', 'merchant_id', 
               'required' => true, 'onDelete' => static::CASCADE],
        'order' => [static::BELONGS_TO, 'Commerce_OrderRecord', 'order_id', 
               'required' => true, 'onDelete' => static::CASCADE],
      ];
  }
}

When I install the plugin I get the following error:

Illegal offset type in isset or empty

If I take away the primaryKey() definition, the table is created successfully and the foreign keys are in place as expected.

Any help gratefully received.

2 Answers 2

2

This should be fixed in the next (post 2.6.2791) release so that plugins can define composite primary keys in their records.

1
  • You boys don't mess around do you! Thanks for the quick turnaround on this, it's much appreciated. Jun 21, 2016 at 7:57
2

It would appear not unfortunately.

Craft's BaseRecord (which a Record should inherit from) tries to uses the primaryKey() method call to help create the table, but assumes a single column name is returned, not an Array and so falls over on the isset call.

$pk = $this->primaryKey();

if (isset($columns[$pk]))
{
  $columns[$pk]['primaryKey'] = true;
  $addIdColumn = false;
}
else
{
  $addIdColumn = true;
}

I'm guessing it should work because the CActiveRecord (which the BaseRecord inherits from) states in it's comments for PrimaryKey:

@return mixed the primary key of the associated database table.

If the key is a composite one consisting of several columns, it should
return the array of the key column names.

EDIT: In the end I added the following to my Plugin file, and that seemed to do the trick:

public function onAfterInstall()
{
  craft()->db->createCommand()->dropColumn('myplugin_merchant_order', 'id');
  craft()->db->createCommand()->addPrimaryKey('myplugin_merchant_order', ['merchant_id', 'order_id']);
}

I also had to add this to my Record, to stop the validation failing because I'd removed the id column in the above step:

public function primaryKey()
{
    return null;
}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.