3

I'm building a plugin and have a form in the plugin's CP page that allows admins to save access codes. The form is a simple textarea where each line is a separate access code.

I'm wondering what the best practice is in terms of inserting these records into the database?

Controller:

// This returns an array of codes to be inserted
$codes = explode("\r\n", craft()->request->getPost('codes'));

foreach($codes as $code) {
    $codeModel = new Portal_CodeModel();
    $codeModel->code = $code;
    $codeModels[] = $codeModel;
}

$success = craft()->portal_code->addCodes($codeModels);

Service:

public function addCodes($codes) {

    foreach($codes as $code) {

      Portal_CodeRecord::model()->insert(array(
          'code'        => $code,
          'code_used'   => 0
      ));

    }

}

Record:

class Portal_CodeRecord extends BaseRecord {

    public function getTableName() {
        return 'portal_codes';
    }

    protected function defineAttributes() {
        return array(
            'code'          => AttributeType::String,
            'code_used'     => AttributeType::Bool
        );
    }
}
1
  • I know there are probably several issues with the above code. If there are any good examples on how to insert multiple records that'd be a huge help. Mar 9, 2015 at 22:12

1 Answer 1

1

Go with #1. It looks like you've already got a Portal_CodeModel created, you just need to populate them from the controller, perform validation (if any), then pass the array of Portal_CodeModel objects to your service.

You'll want to remove the Portal_CodeModel type hint from your service's addCodes signature (or change it to array) since you're passing in an array of objects, instead of a single one.

Here's an example in your controller with any code validation:

$codeModels = array();
$codes = explode("\r\n", craft()->request->getPost('codes'));

$success = craft()->portal_code->addCodes($codes);

And in your service:

public function addCodes($codes)
{

    foreach($codes as $code)
    {
        $existingCode = Portal_CodeRecord::model()->findByAttributes(array(
            'code' => $code,
        ));

        if ($existingCode)
        {
            $existingCode->code_used = 1;
            $existingCode->save();

            {# or whatever else you want to do when the code already exists in the database #}
        }
        else
        {
            $codeRecord = new Portal_CodeRecord();
            $codeRecord->code = $code;
            $codeRecord->code_used = 0;
            $codeRecord->save();
        }
    }

}

8
  • I get the following error with this setup: The active record cannot be inserted to database because it is not new. Mar 10, 2015 at 3:54
  • You'll have to share the actual PHP service code you're using when you get that error, but most likely you're calling insert on a code that already exists in the database when you should be calling update.
    – Brad Bell
    Mar 10, 2015 at 3:56
  • I updated the question based on comments. Mar 10, 2015 at 4:16
  • From all the examples I've seen it shows the instance being created in the service, and then using instanceName->save(); Mar 10, 2015 at 16:30
  • Updated answer.
    – Brad Bell
    Mar 10, 2015 at 16:45

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.