Module: CassandraMapper::Indexing::ClassMethods
- Defined in:
- lib/cassandra_mapper/indexing.rb
Instance Method Summary collapse
-
#has_index(index, options = {}, &block) ⇒ Object
Build an index object and install it into the calling class.
- #install_index(name, index) ⇒ Object
Instance Method Details
#has_index(index, options = {}, &block) ⇒ Object
Build an index object and install it into the calling class.
-
The index argument should be a symbol, which will be the name of the index and the name of the accessor method for that index at both the class level and the instance level.
-
The options hash is passed through to the CassandraMapper::Index constructor, with some minor mapping logic. See the CassandraMapper::Index documentation for most options. Some options specific to this method:
-
class: the class object to use for the index object; use this if you want to provide your own custom index behavior. Defaults to Cassandra::Index. This option determines the class to be instantiated and is not passed along to the constructor.
-
indexed_class: always gets set to the receiver, even if you set it explicitly. This ensures that the index binds to the class against which has_index was called.
-
name: always gets set to the index argument provided to the has_index call, even if you set it explicitly in options.
-
-
If a _&block_ is provided, it will be evaluated in the context of the newly-created index object; this makes it easy to build indexes that have specialized logic for formatting sortable identifiers, etc.
The index is installed as the index attribute of the class object, so all index operations can be accomplished from there. Additionally, the index name is used as an instance attribute, in which an instance’s state relative to the index is tracked. Therefore, choose an index value that you’re happy having on both class and instances.
The index object is activated after installation, so its observer goes into effect immediately.
Given the example class and index described at CassandraMapper::Index, the same strategy could be achieved less verbosely with:
class ToBeIndexed < CassandraMapper::Base
column_family :ToBeIndexed
maps :key, :type => :simple_uuid
maps :data
maps :created_at, :type => :timestamp, :default => :from_type
def
"#{created_at.to_s}_#{key}"
end
has_index :data_index, :source => :data,
:indexed_identifier => :timestamped_key,
:column_family => :Indexes
end
The has_index
invocation takes care of the details for creating the :data_index class and instance attributes, the CassandraMapper::Index instance, its installation and activation, etc.
Finally, if the timestamped key only pertains to this index (as is the case in this example), we could arguably reduce clutter in the main model class and keep the key generation encapsulated in the index by using the block-style invocation.
class ToBeIndexed < CassandraMapper::Base
column_family :ToBeIndexed
maps :key, :type => :simple_uuid
maps :data
maps :created_at, :type => :timestamp, :default => :from_type
has_index :data_index, :source => :data, :column_family => :Indexes do
def indexed_identifier_for(instance)
"#{instance.created_at.to_s}_#{instance.key}"
end
end
end
145 146 147 148 149 150 |
# File 'lib/cassandra_mapper/indexing.rb', line 145 def has_index(index, ={}, &block) klass = .delete(:class) || CassandraMapper::Index object = klass.new(.merge(:indexed_class => self, :name => index)) object.instance_eval &block if block_given? install_index(index, object) end |
#install_index(name, index) ⇒ Object
152 153 154 155 156 157 158 159 |
# File 'lib/cassandra_mapper/indexing.rb', line 152 def install_index(name, index) name_string = name.to_s instance_variable_set(:"@#{name_string}", index) instance_eval "def #{name_string}; @#{name_string}; end" module_eval "def #{name_string}; @#{name_string} ||= CassandraMapper::Index::State.new; end" index.activate! index end |