ActiveModel Integration

When you want a familiar way to populate and search your index without even need to know elasticsearch or when the data you have to index is external to your app (for example if you crawl a site and want to build a searchable index out of it), you can just manage the index like you were managing any active model, still keeping the searching capability of Elastics::Scopes and/or Elastics::Templates.

Notice: The result returned by querying elasticsearch with a Elastics::ActiveModel model, return always regular instance of your class, not the original elasticsearch result structure. However you can always get the raw result by just calling raw_result on the array collection or any model instance.

The key concept is that you create a model per (elasticsearch) type, similarly to what you would do with a DB: a model per table/collection. You do so by including Elastics::ActiveModel which also includes Elastics::ModelIndexer, so you will have all the elastics.* methods available both at the class level and at the instance level (see Elastics::ModelIndexer).

Then you declare the model attributes names, and optionally their default and typecasting. You can eventually set also the elasticsearch mapping properties for each attribute that may need it, and you can use it as any other model. For example:

class Product
  include Elastics::ActiveModel

  # if we omit the next line, the elasticsearch type would have been 'product' by default
  elastics.type = 'goods'

  attribute :name
  # optional elasticsearch properties mapping
  attribute :price, :properties => {'type' => 'float'}, :default => 0

  # :analyzed => false is a shortcut to :properties => { 'type' => 'string', 'index' => 'not_analyzed' }
  attribute :color, :analyzed => false

  # this adds a :created_at and :updated_at attributes
  attribute_timestamps

  # standard validation
  validate :name, :presence => true

  # standard callback
  before_create { self.name = name.titleize }

  # named scope
  scope :red, term(:color => 'red')

end

# indexes the data in elasticsearch
product = Product.new :name  => 'my_name',
                      :color => 'blue',
                      :price => 9.99

product.save if product.valid?

red_products = Product.red.all
product = Product.find('a09rf')
total   = Product.count

Capabilities

By including Elastics::ActiveModel your model gets the following capabilities:

Validation

Validation is provided verbatim by ActiveModel (see activemodel) so you an use all its standard validation methods.

Callbacks

Elastics::ActiveModel provides the create, update, save and destroy callbacks backed by ActiveModel, so you can use them as usual with the before_* and after_* prefixes.

Attributes

By including Elastics::ActiveModel you include also the ActiveAttr::Model. It provides a lot of useful goodies, like attribute declarations with defaults and typecasting (see active_attr). Besides, elastics extends it with a few features (see Class Methods)

Versioning and optimistic lock updating

Elastics::ActiveModel adds the versioning to your models (see elasticsearch Versioning, so your model has always a _version attribute. Besides, it implements the lock updating throught the method lock_update (see Safe Update).

Finders, Scopes and Templates

Elastics::ActiveModel includes also the Elastics::Scopes by default, so you have all the cool finders and chainable scopes ready to use in your model (see elastics-scopes)

Besides, if you need more power to easily write complex queries, you can include the Elastics::Templates module and use it as usual (see Templating)

Methods

(see Elastics::ActiveModel, Elastics::ModelIndexer and Elastics::ModelSyncer)