Validations in ActiveRecord and other mapping frameworks are used to ensure that the data being saved to the database meets the requirements of the app. More importantly, validations are used to communicate to the end user what they need to change about the data they entered.
I often see people using validations to check generated attributes or an attribute set by the controller, and I think that is wrong. Validations should only be used if you to provide your user an opportunity to correct the invalid data.
For example, take this MongoMapper model:
This model is created in an action that looks something like this:
The model is validating the presence of
text, a value supplied by the user, and
game_id. The only way that
game_id can be blank is if there is something wrong the your controller logic. In that unlikely case, your user will be presented with the completely unhelpful error: Game cannot be blank.
game_id should not be a validation that is shown to your user.
But I don’t want to save invalid data!
That’s fine. You can still use the validation callback as an opportunity to verify the data. Add an assertion that the attribute is set. Just don’t add validation errors that get displayed to your user, because no matter what they do, they won’t be able to fix the error that they are seeing. It is more helpful to raise an exception, which will show your user the standard 500 error, and notify you that you’ve got a problem with your application logic.
But what about people hacking?
Do you really want to return friendly error messages to someone trying to hack your app? When trying to secure your app, you want to expose as little information as possible to potential attackers. That’s why it’s even more important to raise errors when validating internal data.
Return friendly error messages for values supplied by your user, and raise big ugly errors when things go wrong.