Flex::ModelSyncer

Notice: Syncing is not needed if you use other external means to sync (like rivers or background jobs).

The Flex::ModelSyncer model is included in Flex::ModelIndexer which is included in Flex::ActiveModel, so they all include the sync-related methods (see Class Methods and Instance Methods). However you may need to explicitly include the Flex::ModelSyncer (see Including Flex::ModelSyncer).

Syncing self

Each time you save or destroy a record belonging to a flex model, you may want to sync the changes with the index. You can implement automatic synchronization by just declaring it. For example:

class Comment
  include Flex::ModelIndexer
  flex.sync self
end

That means that each time a Comment record gets saved or destroyed, Flex will sync self (the Comment instance) with its related elasticsearch document, so the index will always contain the updated data from the DB(s).

Syncing relating models

Sometimes, you may need to sync also other records that are related with the changing record. That is needed when the other record embeds data from the changing record, as in our example with the Parent model (see Indexing Fields). In that case we mapped the indexed source to contain the children.count, so each time we add or remove a Child record, we need also to sync its :parent record (i.e. the self.parent). For example:

class Child
  belongs_to :parent
  include Flex::ModelIndexer
  flex.sync self, :parent
end

That means that besides syncing self, Flex will also sync the :parent parent record.

Propagation

Notice that Flex calls sync on the synced records as well, so also their defined synced models will be synced as well. This feature automatically propagates the syncronization over models, still keeping its implementation very simple on a per-model basis.

Flex tracks the propagation, so it avoids circular references. For example you can sync both the parent from the child and the child from the parent and it will work in either ways, because the propagation will not go backward.

Including Flex::ModelSyncer

Sometimes you may have a model that doesn’t need to be indexed as a document, however part of its data is referred (and indexed) as part of another model. In that case you don’t need the full fledged Flex::ModelIndexer which will add typical index related capabilities to your model (like index, type, store, remove, …). Indeed you need just to sync some other referring model(s). For example:

class NotIndexedModel
  belongs_to :parent
  include Flex::ModelSyncer
  # parts of the data of this model are referred in :parent and :other_model
  flex.sync :parent, :other_model

  def other_model
    # should return the record that needs to be synced
  end

end

In this example, each time a NotIndexedModel record changes, the :parent and the :other_model records will be synced. Notice that a Flex::ModelSyncer.sync cannot sync self: indeed you included that module instead of Flex::ModelIndexer exactly because you don’t need to sync self. :-)

Class Methods

flex.sync(*synced)

With this method you actually define the callback needed to keep the index in sync when the record change, and set the flex.synced array.

It accepts self, symbols and strings. For example:

      flex.sync self, :review, 'blog'
      
  • self will sync the record itself (it is required only for Flex::ModelIndexer models, it’s illegal for Flex::ModelSyncer models and already included for Flex::ActiveModel models)
  • :review is a symbol which identifies a method of the record, which is supposed to return another (relating) record. It is usually a belongs_to association symbol name, but it could be any method that you defined
  • 'blog' is a string which is supposed to be a parent name, as defined in a parent-child map (see elasticsearch Parent/Child Relationship)

When a record of this model changes, it is synced with its related elasticsearch-document, then the record returned by the record.review (must be a flex model) is synced as well, and finally the parent record (defined in the parent/child relationship) is synced IF its type is blog.

flex.synced

Attribute accessor for the Array of items to sync. You may need to set this Array only in the very special case that you want to sync the record manually. In that case you should not use the flex.sync that does it automatically. (see also record.flex.sync below). If you use Model.flex.sync you can ignore this.

flex.refresh_index

It refreshes the index by using Flex.refresh_index API method. For automatic refresh you can also use Flex::RefreshCallback (see Flex::RefreshCallback).

Instance Methods

flex.sync

It syncs the list of synced models, as set in the flex.synced array. This method is automatically called when the record changes, so you probably don’t need to use it explicitly. If you need to sync manually, then you should not use Model.flex.sync(*synced) which will define the callbacks. Instead you should use Model.flex.synced = [self, :other, ...] that causes the same behaviour, without setting the callbacks.

flex.refresh_index

It refreshes the index by using Flex.refresh_index API method. For automatic refresh you can also use Flex::RefreshCallback (see Flex::RefreshCallback).