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.