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
        );
    }
}
  • 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. – Brett DeWoody Mar 9 '15 at 22:12
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();
        }
    }

}

  • I get the following error with this setup: The active record cannot be inserted to database because it is not new. – Brett DeWoody Mar 10 '15 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 '15 at 3:56
  • I updated the question based on comments. – Brett DeWoody Mar 10 '15 at 4:16
  • From all the examples I've seen it shows the instance being created in the service, and then using instanceName->save(); – Brett DeWoody Mar 10 '15 at 16:30
  • Updated answer. – Brad Bell Mar 10 '15 at 16:45

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.