ActiveModel validations without a model

The other day someone on Stack Overflow asked how to validate inputs without having a model.

I kind of liked my answer, so I am more or less reposting it here — with some extra thoughts.

The Rails Way (tm)

The Rails Way is having validations tied to ActiveRecord classes, and where that doesn’t make sense, construct other classes and include ActiveModel::Validations.

Occasionally this might be too heavy-handed, I guess, or you might have dynamic validations, or you might disagree with having validations in the model layer on sheer principle.

The Laravel Way?

The original question used an example from Laravel, where validations do not live inside models. Rather, you construct a validator that can tell you if a set of inputs is valid given a set of validations.

An action following that pattern might look like this in a Rails application:

validator = DataValidator.make(
    :email => {:presence => true},
    :name => {:presence => true}
if validator.valid?
  # Success
  # Error
	@errors = validator.errors

Simple enough, huh?

The code for this is fairly simple as well and basically defines an anonymous class on the fly, returning an instance of that class:

class DataValidator
  def self.make(data, validations) do
      include ActiveModel::Validations


      validations.each do |attribute, options|
        validates attribute, options

      def self.model_name, nil, "DataValidator::Validator")

      def initialize(data)
        data.each do |key, value|
          self.send("#{key.to_sym}=“, value)

What’s up with validating data in models, anyways?

Writing the above code also got me thinking; why exactly do we not always validate inputs like this? Why do we insist on validating user input in our models?