<p>I'm pretty sure <code>'default'=&gt;[]</code> isn't doing anything so it's probably not necessary.</p>

<p>If you wanted to force a single attribute to be of a specific model, you could use:</p>

<pre><code>'courierShippingItems'  =&gt; array('type' =&gt; AttributeType::Mixed, 'model' =&gt; 'Shipper_ShippingItemModel');
</code></pre>

<p>Regardless, you'll want to use BaseModel's <a href="https://github.com/pixelandtonic/Craft-Release/blob/master/app/models/BaseModel.php#L355" rel="nofollow">setAttribute</a> to do what you're trying to do and build your entire array up first before assigning it to the attribute.  Something like this:</p>

<pre><code>$shippingItems[] = Shipper_ShippingItemModel::populateModel($data);

$results-&gt;setAttribute('courierShippingItems', $shippingItems);
</code></pre>

CC BY-SA 3.0
2015-09-28T23:52:31.773Z
Thanks Brad - I am now doing it like this, although simply building the array in a separate variable, and then assigning it directly at the end, rather than using setAttribute, appears to work fine as well.
Jeremy Daalder
CC BY-SA 3.0
2015-09-27T21:21:31.103Z
2015-09-27T21:21:31.103Z
Brad Bell
<p>I have a model that contains a bunch of storage arrays where I collect results from various services I have written.</p>

<pre><code>class Shipper_ResultsModel extends BaseModel
{
</code></pre>

<p>shipping categories for debugging</p>

<pre><code>    protected function defineAttributes()
    {
        return array(
            'service'               =&gt; array('type'=&gt;AttributeType::Enum, 'values'=&gt;['post','courier','free','cantShip','needsQuote']),
            'options'               =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
            'boxes'                 =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
            'postShippingItems'     =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
            'courierShippingItems'  =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
            'freeShippingItems'     =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
            'cantShippingItems'     =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
            'quoteShippingItems'    =&gt; array('type'=&gt;AttributeType::Mixed,'default'=&gt;[]),
        );
    }
</code></pre>

<p>Each of this <code>ShippingItems</code> arrays is intended to hold an array of Shipper_ShippingItem models.</p>

<p>My issue is in building these arrays, I create new items and add them like this:</p>

<pre><code>            $shippingItem = Shipper_ShippingItemModel::populateModel($data);

            //build our arrays of items
            if($shippingClass=="Courier Only"){
                $results-&gt;courierShippingItems[] = $shippingItem;
            }
</code></pre>

<p>But this results in the following error:</p>

<pre><code>PHP Notice: Indirect modification of overloaded property Craft\Shipper_ResultsModel::$courierShippingItems has no effect
</code></pre>

<p>I think this is because I am not using array objects as such but I have to say I've  got a little confused here and various syntax experiments have resulted in ignoble failures.</p>

<p>Some guidance as to the right way would be much appreciated (and am I right in using <code>AttributeType::Mixed</code> for these?)</p>

<p>(This is all for a mega shipping calculator for Craft Commerce, should that matter)</p>

<plugin-development><php><models><array><yii>
How to add to arrays in models?
# How to add to arrays in models?

(Asked by: username_0 on 2015-09-27)

I have a model that contains a bunch of storage arrays where I collect results from various services I have written.
class Shipper_ResultsModel extends BaseModel
{

shipping categories for debugging
    protected function defineAttributes()
    {
        return array(
            'service'               => array('type'=>AttributeType::Enum, 'values'=>['post','courier','free','cantShip','needsQuote']),
            'options'               => array('type'=>AttributeType::Mixed,'default'=>[]),
            'boxes'                 => array('type'=>AttributeType::Mixed,'default'=>[]),
            'postShippingItems'     => array('type'=>AttributeType::Mixed,'default'=>[]),
            'courierShippingItems'  => array('type'=>AttributeType::Mixed,'default'=>[]),
            'freeShippingItems'     => array('type'=>AttributeType::Mixed,'default'=>[]),
            'cantShippingItems'     => array('type'=>AttributeType::Mixed,'default'=>[]),
            'quoteShippingItems'    => array('type'=>AttributeType::Mixed,'default'=>[]),
        );
    }

Each of this ShippingItems arrays is intended to hold an array of Shipper_ShippingItem models.
My issue is in building these arrays, I create new items and add them like this:
            $shippingItem = Shipper_ShippingItemModel::populateModel($data);

            //build our arrays of items
            if($shippingClass=="Courier Only"){
                $results->courierShippingItems[] = $shippingItem;
            }

But this results in the following error:
PHP Notice: Indirect modification of overloaded property Craft\Shipper_ResultsModel::$courierShippingItems has no effect

I think this is because I am not using array objects as such but I have to say I've  got a little confused here and various syntax experiments have resulted in ignoble failures.
Some guidance as to the right way would be much appreciated (and am I right in using AttributeType::Mixed for these?)
(This is all for a mega shipping calculator for Craft Commerce, should that matter)

**Tags:** plugin-development, php, models, array, yii


---

## 1 answers

### Answer by username_1 on 2015-09-27. Score: 2 | Accepted answer

I'm pretty sure 'default'=>[] isn't doing anything so it's probably not necessary.
If you wanted to force a single attribute to be of a specific model, you could use:
'courierShippingItems'  => array('type' => AttributeType::Mixed, 'model' => 'Shipper_ShippingItemModel');

Regardless, you'll want to use BaseModel's setAttribute to do what you're trying to do and build your entire array up first before assigning it to the attribute.  Something like this:
$shippingItems[] = Shipper_ShippingItemModel::populateModel($data);

$results->setAttribute('courierShippingItems', $shippingItems);

> **Comments:**
> **username_0**: Thanks Brad - I am now doing it like this, although simply building the array in a separate variable, and then assigning it directly at the end, rather than using setAttribute, appears to work fine as well.  

---

