0

I'm having trouble saving some data into the database with my plugin. I am able to save content only if an index is defined on that column, but only if unique=>true is set, which causes some problems because I need repeated values in column b. My function that runs after plugin install works, as I am able to save all the correct content in column A. Data is saved in column b if I set a unique index on it, otherwise the column fills with Null. Any help is greatly appreciated!

Model:

namespace Craft;

class Plugin_MyModel extends BaseModel
{
    public $a = "";
    public $b = "";

    protected function defineAttributes()
    {
        return array(
            'a' => AttributeType::String,
            'b' => AttributeType::String,
        );
    }
}

Record:

<?php

namespace Craft;

class Plugin_MyRecord extends BaseRecord
{
    public function getTableName()
    {
        return 'my_table';
    }

    protected function defineAttributes()
    {
        return array(
            'a'     => AttributeType::String,
            'b' => AttributeType::String,
        );
    }

    public function defineIndexes()
    {
        return array(
            array('columns' => array('a'), 'unique' => true),
        );
    }
}

Service that gets data from API call and attempts to save in DB:

<?php

namespace Craft;

class Plugin_MyService extends BaseApplicationComponent
{

    protected $myRecord;

    public function __construct($myRecord = null)
    {
        $this->myRecord = $myRecord;
        if(is_null($this->myRecord))
        {
            $this->myRecord = Plugin_MyRecord::model();
        }   
    }


    public function saveItem(Plugin_MyModel &$model)
    {
        if ($id = $model->getAttribute('id')) {
            if (null === ($record = $this->myRecord->findByPk($id))) {
                throw new Exception(Craft::t('Can\'t find item with ID "{id}"', array('id' => $id)));
            }
        } else {
            $record = $this->myRecord->create();
        }

        $record->setAttributes($model->getAttributes());
        if ($record->save()) {
            // update id on model (for new records)
            $model->setAttribute('id', $record->getAttribute('id'));

            return true;
        } else {
            $model->addErrors($record->getErrors());

            return false;
        }
    }


    public function loadAllItems()
    {
        $items = $this->api();

        foreach($items['Items'] AS $item)
        {        
            $new_item = new Plugin_MyModel();
            $new_item->a = $item['a'];
            $new_item->b = $item['b'];
            $this->saveItem($new_item);
        }
    }

    private function api(){
        //Returns API Data  
    }
}
  • 1) Can you post the code you're using to save to the database and 2) What's the point of the public $a and $b properties on the model? – Brad Bell Sep 28 '14 at 1:22
  • 1
    When you’re making changes to your record, are you also updating the DB table? The only time Craft will automatically make DB schema changes for you is right when you install a plugin. – Brandon Kelly Sep 28 '14 at 12:17
  • Just added the Service class that gets data from an API call and attempts to save it into the DB. Thanks for taking a look! – Aaron Berkowitz Sep 28 '14 at 16:08
  • Awesome. Can you add that as the official answer? – Brad Bell Sep 28 '14 at 20:33
  • Sorry, just saying that I put the Service class in the code above for review. Still not working properly. – Aaron Berkowitz Sep 28 '14 at 22:05
2

I had a similar problem, ended up using multiple setAttribute() calls instead of setAttributes().

I created an array of attributes separately and then looped through them and called setAttribute for each one, seemed to do the trick.

if ($id = $model->getAttribute('id')) {
    if (null === ($record = $this->myRecord->findByPk($id))) {
            throw new Exception(Craft::t('Can\'t find item with ID "{id}"', array('id' => $id)));
        }
    } else {
        $record = $this->myRecord->create();
    }

    /* Not this: */       
    $record->setAttributes($model->getAttributes());

    /* This instead: */
    $attributes = array(
        'column1' => $col1,
        'column2' => $col2
    );    
    foreach($attributes as $k => $v) $record->setAttribute($k,$v);
}
| improve this answer | |
  • I also had this exact problem once. I used the above solution to get me rolling, but help from others to finally resolve it. Check out my thread to see what was causing the problem. TL;DR: validation is causing it. – Damon Apr 8 '15 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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