<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>

CC BY-SA 3.0
2014-11-29T04:24:15.853Z
2014-11-29T04:24:15.853Z
Brad Bell
<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>

CC BY-SA 3.0
2014-12-02T16:51:25.013Z
2014-12-02T16:51:25.013Z
Ben Croker
<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>

<plugin-development><best-practice><models><records><services>
Populate a record with a model?
# 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.


---

