Home > Articles > Web Development

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

9.12 Nonpersisted Models

In Rails 3, if one wanted to use a standard Ruby object with Action View helpers, such as form_for, the object had to “act” like an Active Record instance. This involved including/extending various Active Model module mixins and implementing the method persisted?. At a minimum, ActiveModel::Conversion should be included and ActiveModel::Naming extended. These two modules alone provide the object all the methods it needs for Rails to determine partial paths, routes, and naming. Optionally, extending ActiveModel::Translation adds internationalization support to your object, while including ActiveModel::Validations allows for validations to be defined. All modules are covered in detail in the Active Model API Reference.

To illustrate, let’s assume we have a Contact class that has attributes for name, email, and message. The following implementation is Action Pack and Action View compatible in both Rails 3 and 4:


 1 class Contact
 2   extend ActiveModel::Naming
 3   extend ActiveModel::Translation
 4   include ActiveModel::Conversion
 5   include ActiveModel::Validations
 6
 7   attr_accessor :name, :email, :message
 8
 9   validates :name, presence: true
10   validates :email,
11     format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]
         {2,})\z/ },
12     presence: true
13   validates :message, length: {maximum: 1000}, presence: true
14
15   def initialize(attributes = {})
16     attributes.each do |name, value|
17       send("#{name}=", value)
18     end
19   end
20
21   def persisted?
22     false
23   end
24 end

New to Rails 4 is the ActiveModel::Model, a module mixin that removes the drudgery of manually having to implement a compatible interface. It takes care of including/extending the modules mentioned earlier, defines an initializer to set all attributes on initialization, and sets persisted? to false by default. Using ActiveModel::Model, the Contact class can be implemented as follows:


 1 class Contact
 2   include ActiveModel::Model
 3
 4   attr_accessor :name, :email, :message
 5
 6   validates :name, presence: true
 7   validates :email,
 8     format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/ },
 9     presence: true
10   validates :message, length: {maximum: 1000}, presence: true
11 end
  • + Share This
  • 🔖 Save To Your Account