Ruby on Rails - Active Model



In the earlier chapters of this tutorial, we explained the Active Record ORM in Ruby on Rails framework. Active Record is an ORM (Object Relational Mapper) that connects objects whose data requires persistent storage to a relational database. One of the functionality of Active Record is to form Active Model. In this chapter, we will explore the features of Rails Active Model.

Relation between Active Model and Active Record

The relation between Active Model and Active Record can be stated as follows −

  • Active Record includes Active Model.
  • Every Active Record object has all the capabilities of Active Model plus persistence.

Hence, you will use the Active Record when you need to persist data in a database, whereas you need to use the Active Model when you need form-like models (e.g., ContactForm, SearchForm, Payment) that don’t need to be stored in the database.

Rails Active Model Features

Active Model is a library containing various modules that presents a set of interfaces and minimal functionalities for building model-like classes without having to use a database.

Features of Active Model include −

  • Validations (validates)
  • Callbacks (before_validation, etc.)
  • Naming and conversion (e.g., model_name)
  • Serialization (e.g., to_json, to_xml)
  • Error handling (errors.add, errors.full_messages)
  • Dirty tracking (attribute_changed?)

Note − Active Model allows non-persistent Ruby objects (i.e., not backed by a DB) to behave like Active Record objects in terms of form handling, validation, and serialization.

Here are some more features of Rails Active Model −

  • ActiveModel::API to interact with Action Pack and Action View by default, and is the recommended approach to implement model-like Ruby classes.
  • The Active Model class has Attributes with which you can define data types, set default values. To use Attributes, include the module in your model class and define your attributes.
  • Inside the Active Model class, you may have one or more callback functions to hook into model lifecycle events, such as before_update and after_create.
  • ActiveModel::Serialization provides basic serialization for your object. An attribute hash (must be strings, not symbols) hash should contain the attributes you want to serialize.
  • Another feature is ActiveModel::Validations that adds the ability to validate objects and it is important for ensuring data integrity and consistency within your application.

Example: Active Model in Rails Application

Let us use Active Model in the following Rails application. To start with, create an application and declare a Book scaffold as below −

rails new myapp
cd myapp
rails generate scaffold Book title:string author:string
rails db:migrate

Create the Active Model

Create a forms folder under the app folder in your project directory and declare the BookForm class acting as the Active Model −

# app/forms/book_form.rb
class BookForm
	include ActiveModel::Model
	include ActiveModel::Attributes

	attribute :title, :string
	attribute :author, :string

	validates :title, :author, presence: true

	def save
		return false unless valid?

		Book.create(title: title, author: author)
	end
end

Update the Controller

Update the controller to use BookForm. Open the BooksController class and modify the create action −

# app/controllers/books_controller.rb
def new
	@book_form = BookForm.new
end

def create
	@book_form = BookForm.new(book_form_params)

	if @book_form.save
		redirect_to books_path, notice: "Book was successfully created."
	else
		render :new, status: :unprocessable_entity
	end
end

Update the Form View

Rails has already created a view as new.html.erb file. Open it and edit the same to include the following code −

<%= form_with model: @book_form, url: books_path, local: true do |form| %>
   <% if @book_form.errors.any? %>
      <div id="error_explanation">
         <h2><%= pluralize(@book_form.errors.count, "error") %> 
         prohibited this book from being saved:</h2>
         <ul>
            <% @book_form.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
            <% end %>
         </ul>
      </div>
   <% end %>

   <div class="field">
      <%= form.label :title %>
      <%= form.text_field :title %>
   </div>

   <div class="field">
      <%= form.label :author %>
      <%= form.text_field :author %>
   </div>

   <div class="actions">
      <%= form.submit "Create Book" %>
   </div>
<% end %>

That’s it. Save the changes and run the Rails server. Visit http://localhost:3000/books/new to display a New Book form.

Rails Active Model1

Try clicking the Create Book button without entering any data −

Rails Active Model2

The error messages will be flashed as below −

Rails Active Model3

This time around, enter the title and author fields and submit the data. Rails will display a confirmation as below −

Rails Active Model4

In this example, we used the Book model (Active Record) which is mapped to the books table in the database. On the other hand, BookForm is the Active Model object. The attributes of the Active Model are not stored persistently in the database. It is used for validation and abstraction.

Advertisements