What is Active Model?

Last week we looked at using Form Objects to remove some of the burden of validation from our Active Record models.

A Form Object is basically just a plain Ruby Object that is able to quack like an Active Record object.

One thing that I mentioned, but skipped over last week was Active Model.

Active Model is a library of modules used for developing classes that need certain aspects of Active Record’s functionality.

In today’s tutorial we will be looking at using Active Model.

What is Active Model?

As I mentioned in Getting started with Active Record in Ruby on Rails, Ruby on Rails has a very powerful implementation of the Active Record pattern.

Active Record also has a lot of functionality that would be useful outside of the ORM.

For example, validations, serialisations, and translations are important aspects of ActiveRecord, but could also be used outside of the context of an ORM.

To prevent reinventing the wheel every time you wanted to add this kind of functionality to other Ruby objects, Active Model was abstracted from Active Record.

This makes it very easy to add this functionality to your ruby objects.

Active Model is basically just a set of modules you can include in your Ruby objects to add certain aspects of functionality from Active Record.

Validation

One aspect of Active Model that we’ve already seen is Validation.

Validation is a very important aspect of a web application, but it doesn’t always occur only in the model.

As we saw in last week’s tutorial we could also use Form Objects for particular processes like registration, resetting passwords or other common processes that require data input from the user.

Validation is also important when creating Domain Objects to represent core components of your application.

For example, imagine we had a Book class:

class Book

end  

A book should always have an title and a isbn in order for it to be “valid”.

We can ensure that this is the case by including ActiveModel::Validations:

class Book  
include ActiveModel::Validations

attr_accessor :name, :isbn

validates :name, presence: true  
validates :isbn, presence: true  
end  

Now we can use the Book class like any other object, but we now have the power of Active Model Validations:

book = Book.new  
book.valid? # false

book.name = "The Four Hour Work Week"  
book.isbn = "123"  
book.valid? # true  

Dirty

Another useful module you can include on your plain Ruby objects is the Dirty module. This will allow you to detect if any of the properties of the object have been changed:

class Book  
include ActiveModel::Dirty  
define_attribute_methods :name, :isbn

def name  
@name  
end

def name=(value)  
name_will_change!  
@name = value  
end

def isbn  
@isbn  
end

def isbn=(value)  
isbn_will_change!  
@isbn = value  
end  
end  

Now you can query the object to see if any of the properties have changed:

book = Book.new  
book.changed? # false

book.name = "Crushing it!"  
book.changed? # true

book.changes # {"name"=>[nil, "Crushing it!"]}

book.name_changed? # true  
book.isbn_changed? # false

book.name_was # nil  
book.name_change # [nil, "Crushing it!"]

book.isbn_was # nil  
book.isbn_change # nil  

Serialisation

The Serialisation module allows you to serialise your objects into a number of different formats.

class Book  
include ActiveModel::Serializers::JSON

attr_accessor :name, :isbn

def attributes  
{"name" => nil, "isbn" => nil}  
end  
end  

Your Ruby object will now have access to the as_json method to return the object as JSON:

book = Book.new  
book.name = "Fooled by Randomness"  
book.isbn = "123"

book.as_json # {"name":"Fooled by Randomness","isbn":"123"}  

If you wanted to switch from JSON to XML, you will only need to change the included module:

class Book  
include ActiveModel::Serializers::XML

attr_accessor :name, :isbn

def attributes  
{"name" => nil, "isbn" => nil}  
end  
end  

Conclusion

By abstracting these common modules out of Active Record, we have been blessed with a very simply way of adding certain types of functionality to our ruby objects.

Nobody in their right mind wants to write a validation library from scratch, and so simply including the already build Active Record validation module is as simple as can be.

As we saw in last week’s tutorial, sometimes we need an object that can quack like an Active Record object. By using the modules of Active Model, this is a very easy thing to accomplish!

What is Active Model?
Share this