<p><a href="http://buildwithcraft.com/docs/plugins/records">Records</a> and <a href="http://buildwithcraft.com/docs/plugins/models">models</a> are similar in that they are both containers for data, but records have the additional functionality/overhead of being able to write and read from the database via the <a href="http://www.yiiframework.com/doc/guide/1.1/en/database.ar">Active Record</a> pattern.  There is also not a 1:1 relationship between records and models.  A model can define attributes from multiple records.</p>

<p>In practice, records should never leave your <a href="http://buildwithcraft.com/docs/plugins/services">service layer</a>, because you don't want them floating up to the controller or template level, for example.  If that happened, then people could inadvertently insert/update/overwrite data directly from a template.</p>

<p>From your service, you do all of your Active Record / database related logic, and call <a href="http://buildwithcraft.com/classreference/models/BaseModel#populateModel-detail">populateModel(s)</a> with the resulting data and return the models from your service and let those safely transport your data throughout your layers.</p>

<p>The general pattern for all of this, including validation, looks like this:</p>

<pre><code>class SomeController extends BaseController
{
    public function actionDoSomething()
    {
        $myModel = new MyModel();
        $myModel-&gt;myProperty = 1;

        // Validate the model
        if ($myModel-&gt;validate())
        {
            // Pass it to the service.
            if (craft()-&gt;myService-&gt;doSomething($myModel))
            {
                // Success!
                $this-&gt;redirectToPostedUrl();
            }
        }

        // Return the model back to the template so the errors can be displayed.
        craft()-&gt;urlManager-&gt;setRouteVariables(array(
            'model' =&gt; $myModel
        ));
    }
}
</code></pre>

<p>Your service can grab the info it needs from the model and create or grab any necessary records.  It can then, if it needs to, call <code>$record-&gt;validate()</code> on any of the records.  If a record fails validation in the service, it can add those errors to the original model and return false like:</p>

<pre><code>$myModel-&gt;addErrors($record-&gt;getErrors);
</code></pre>

<p>And those errors will bubble up to the template to be displayed.</p>

CC BY-SA 3.0
2014-10-08T05:20:11.767Z
Rock solid answer. Now I know which direction to go. Thanks Brad. :)
naboovalley
CC BY-SA 3.0
2014-11-01T08:17:25.273Z
This is the type of example that should be on the documentation page. Great question and great answer!
Jason McCallister
CC BY-SA 3.0
2014-12-04T04:39:35.853Z
I agree, this is a great answer and is a good example of what should be in the documentation. I'm still curious about the defineAttributes() method. Both the model and record have it and with your method we are forced to repeat a lengthy method definition in both our model and record. Am I missing something? Any suggestions?
coffe4u
CC BY-SA 3.0
2014-12-04T04:56:23.333Z
If they're identical, then I wouldn't consider a copy/paste lengthy. :) Repetitive, perhaps. But this way, you get the flexibility of having a model map to multiple records and custom model attribute validation that might go beyond the more simplistic needs of a record.
Brad Bell
CC BY-SA 3.0
2014-10-07T18:33:57.307Z
2014-10-07T18:33:57.307Z
Brad Bell
<p>I'm trying to wrap my head around when to use a Model and when to use a Record (or both?).</p>

<p>I have both my Model and my Record. In my Controller I call my Service that creates my new Record instance before running the <code>-&gt;save();</code> command to save my new entry into the database.</p>

<p>Since my Record can run the validation process from my specified <code>rules()</code> array I'm wondering what I have my Model for?</p>

<p>Also since I'm running the actual database command from within my Service and dont have access to the Record in my Controller, how do I return the validation errors to my Controller for later use in my template variables?</p>

<p>Or do I run the validation on my Model in my Controller as well? Seems like I'll be doing the same thing twice if so.... or what am I not getting here? :P</p>

<plugin-development>
Where do I run validation before database insert?
# Where do I run validation before database insert?

(Asked by: username_0 on 2014-10-07)

I'm trying to wrap my head around when to use a Model and when to use a Record (or both?).

I have both my Model and my Record. In my Controller I call my Service that creates my new Record instance before running the `->save();` command to save my new entry into the database.

Since my Record can run the validation process from my specified `rules()` array I'm wondering what I have my Model for?

Also since I'm running the actual database command from within my Service and dont have access to the Record in my Controller, how do I return the validation errors to my Controller for later use in my template variables?

Or do I run the validation on my Model in my Controller as well? Seems like I'll be doing the same thing twice if so.... or what am I not getting here? :P

**Tags:** plugin-development

---

## 1 answers

### Answer by username_1 on 2014-10-07. Score: 13 | Accepted answer

Records and models are similar in that they are both containers for data, but records have the additional functionality/overhead of being able to write and read from the database via the Active Record pattern.  There is also not a 1:1 relationship between records and models.  A model can define attributes from multiple records.
In practice, records should never leave your service layer, because you don't want them floating up to the controller or template level, for example.  If that happened, then people could inadvertently insert/update/overwrite data directly from a template.
From your service, you do all of your Active Record / database related logic, and call populateModel(s) with the resulting data and return the models from your service and let those safely transport your data throughout your layers.
The general pattern for all of this, including validation, looks like this:
class SomeController extends BaseController
{
    public function actionDoSomething()
    {
        $myModel = new MyModel();
        $myModel->myProperty = 1;

        // Validate the model
        if ($myModel->validate())
        {
            // Pass it to the service.
            if (craft()->myService->doSomething($myModel))
            {
                // Success!
                $this->redirectToPostedUrl();
            }
        }

        // Return the model back to the template so the errors can be displayed.
        craft()->urlManager->setRouteVariables(array(
            'model' => $myModel
        ));
    }
}

Your service can grab the info it needs from the model and create or grab any necessary records.  It can then, if it needs to, call $record->validate() on any of the records.  If a record fails validation in the service, it can add those errors to the original model and return false like:
$myModel->addErrors($record->getErrors);

And those errors will bubble up to the template to be displayed.

> **Comments:**
> **username_0**: Rock solid answer. Now I know which direction to go. Thanks Brad. :)  
> **username_2**: This is the type of example that should be on the documentation page. Great question and great answer!  
> **username_3**: I agree, this is a great answer and is a good example of what should be in the documentation. I'm still curious about the defineAttributes() method. Both the model and record have it and with your method we are forced to repeat a lengthy method definition in both our model and record. Am I missing something? Any suggestions?  
> **username_1**: If they're identical, then I wouldn't consider a copy/paste lengthy. :) Repetitive, perhaps. But this way, you get the flexibility of having a model map to multiple records and custom model attribute validation that might go beyond the more simplistic needs of a record.  

---

