Answers.Body: <p>Yii does have the equivalent <a href="http://www.yiiframework.com/doc/api/1.1/CActiveRecord#populateRecord-detail" rel="nofollow">populateRecord</a> and <a href="http://www.yiiframework.com/doc/api/1.1/CActiveRecord#populateRecords-detail" rel="nofollow">populateRecords</a> on <a href="http://www.yiiframework.com/doc/api/1.1/CActiveRecord" rel="nofollow">CActiveRecord</a>.</p>
  
  <p>However, on both the populateModel(s) and populateRecord(s) methods, you should be very cautious of blindly mass-assigning untrusted inputs to models/records that participate in the Active Record pattern (like Craft/Yii does).</p>
  
  <p>They can be susceptible to what's known as the <a href="https://en.wikipedia.org/wiki/Mass_assignment_vulnerability" rel="nofollow">Mass Assignment Vulnerability</a> that many popular frameworks have been a victim of.</p>
  
  <p>Yii does what it can to protect against this, but my personal preference is to explicitly assign each individual attributes on the model/record in the case of untrusted input to avoid the issue altogether.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-29T04:24:15.853Z
Answers.LastActivityDate: 2014-11-29T04:24:15.853Z
Answers.UserDisplayName: Brad Bell
Answers.Body: <p>Yii's <a href="http://www.yiiframework.com/doc/api/1.1/CModel#setAttributes-detail" rel="nofollow">setAttributes</a> method is probably a better way to do this than the <a href="http://www.yiiframework.com/doc/api/1.1/CActiveRecord#populateRecords-detail" rel="nofollow">populateRecords</a> method, as by default assignments will only be made to safe attributes.</p>
  
  <p>See this wiki article, <a href="http://www.yiiframework.com/wiki/161/" rel="nofollow">Understanding "Safe" Validation Rules </a>, for details on how you can specify what attributes are safe to be massively assigned. This will allow you to protect against unwanted assignment from untrusted sources.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-12-02T16:51:25.013Z
Answers.LastActivityDate: 2014-12-02T16:51:25.013Z
Answers.UserDisplayName: Ben Croker
Body: <p>In a follow up to my earlier question, I'm focusing on cleaning up my code to keep it incredibly simple. I've moved on from the Controller and Model to the Model and Service. Typically you would have something like the following in a service method:</p>
  
  <pre><code>$record = new MyRecord();
  
  $record-&gt;name           = $model-&gt;name;
  $record-&gt;anotherField   = $model-&gt;anotherField;
  // etc..
  </code></pre>
  
  <p>Which works and you end up defining the attributes in <code>_attributes</code> as an array like below:</p>
  
  <pre><code>[*:_attributes] =&gt; array
      (
          'uid' =&gt; '0'
          'name' =&gt; 'My Name'
          'anotherField' =&gt; 'Another Field'
      )
  </code></pre>
  
  <p>The logic that I am looking for, which I'm sure someone will tell me I am just using the wrong method, can be seen in the controller.</p>
  
  <pre><code>public function actionSave()
      {
          // require a post request
          $this-&gt;requirePostRequest();
  
          // assign the fields from post request
          $post = craft()-&gt;request-&gt;getPost('fields');
  
          // create a model, populate with the assigned fields
          $model = MyModel::populateModel($post);
  
          // validate attributes
          if ($model-&gt;validate()) {
  
              // save the record
              craft()-&gt;myPlugin-&gt;saveNew($model);
  
              // redirect to posted url
              $this-&gt;redirectToPostedUrl();
          }
  
          // grab errors from the model
          $errors = $model-&gt;getErrors();
  
          // return errors to the template as 'errors'
          craft()-&gt;urlManager-&gt;setRouteVariables(array(
              'errors'    =&gt; $errors
          ));
      }
  </code></pre>
  
  <p>In the controller code, I'm populating the <code>model</code> with the <code>post</code> with this line:</p>
  
  <pre><code>`$model = MyModel::populateModel($post);`
  </code></pre>
  
  <p>Is there a way to create the same behavior for the method in the service to "automagically" assign the model attributes to the <code>$record</code>?</p>
  
Tags: <plugin-development><best-practice><models><records><services>
Title: Populate a record with a model?
ThreadText: # Populate a record with a model?
  
  (Asked by: username_0 on 2014-11-29)
  
  In a follow up to my earlier question, I'm focusing on cleaning up my code to keep it incredibly simple. I've moved on from the Controller and Model to the Model and Service. Typically you would have something like the following in a service method:
  
  ```
  $record = new MyRecord();
  
  $record->name           = $model->name;
  $record->anotherField   = $model->anotherField;
  // etc..
  
  ```
  
  Which works and you end up defining the attributes in `_attributes` as an array like below:
  
  ```
  [*:_attributes] => array
      (
          'uid' => '0'
          'name' => 'My Name'
          'anotherField' => 'Another Field'
      )
  
  ```
  
  The logic that I am looking for, which I'm sure someone will tell me I am just using the wrong method, can be seen in the controller.
  
  ```
  public function actionSave()
      {
          // require a post request
          $this->requirePostRequest();
  
          // assign the fields from post request
          $post = craft()->request->getPost('fields');
  
          // create a model, populate with the assigned fields
          $model = MyModel::populateModel($post);
  
          // validate attributes
          if ($model->validate()) {
  
              // save the record
              craft()->myPlugin->saveNew($model);
  
              // redirect to posted url
              $this->redirectToPostedUrl();
          }
  
          // grab errors from the model
          $errors = $model->getErrors();
  
          // return errors to the template as 'errors'
          craft()->urlManager->setRouteVariables(array(
              'errors'    => $errors
          ));
      }
  
  ```
  
  In the controller code, I'm populating the `model` with the `post` with this line:
  
  ```
  `$model = MyModel::populateModel($post);`
  
  ```
  
  Is there a way to create the same behavior for the method in the service to "automagically" assign the model attributes to the `$record`?
  
  **Tags:** plugin-development, best-practice, models, records, services
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2014-11-29. Score: 2 | Accepted answer
  
  Yii does have the equivalent [populateRecord](http://www.yiiframework.com/doc/api/1.1/CActiveRecord#populateRecord-detail) and [populateRecords](http://www.yiiframework.com/doc/api/1.1/CActiveRecord#populateRecords-detail) on [CActiveRecord](http://www.yiiframework.com/doc/api/1.1/CActiveRecord).
  
  However, on both the populateModel(s) and populateRecord(s) methods, you should be very cautious of blindly mass-assigning untrusted inputs to models/records that participate in the Active Record pattern (like Craft/Yii does).
  
  They can be susceptible to what's known as the [Mass Assignment Vulnerability](https://en.wikipedia.org/wiki/Mass_assignment_vulnerability) that many popular frameworks have been a victim of.
  
  Yii does what it can to protect against this, but my personal preference is to explicitly assign each individual attributes on the model/record in the case of untrusted input to avoid the issue altogether.
  
  
  ---
  
  ### Answer by username_2 on 2014-12-02. Score: 2
  
  Yii's [setAttributes](http://www.yiiframework.com/doc/api/1.1/CModel#setAttributes-detail) method is probably a better way to do this than the [populateRecords](http://www.yiiframework.com/doc/api/1.1/CActiveRecord#populateRecords-detail) method, as by default assignments will only be made to safe attributes.
  
  See this wiki article, [Understanding "Safe" Validation Rules](http://www.yiiframework.com/wiki/161/) , for details on how you can specify what attributes are safe to be massively assigned. This will allow you to protect against unwanted assignment from untrusted sources.
  
  
  ---
  
  