TL;DR: This Gist sketches out an API for providing a means of managing inheritable indexing configurations in ActiveFedora. Primary motivations are (1) to avoid (for most purposes) putting indexing logic in an overriden #to_solr method, and (2) to make it possible to introspect a model's or instance’s indexing.
An earlier version of this idea was kicked around on IRC, and I've refined it significantly since then, mainly to accommodate the current property indexing API (from ActiveTriples). Originally, I just aimed to deal with indexing calculated values (basically model methods, as opposed to attributes or properties which already support indexing), for which one currently has to override #to_solr.
Essentially, I wanted to be able to do this type of thing on a model:
# Stupid example
class Image < ActiveFedora::Base
# index key, *args [, &block]
# key is interpreted as method name unless block is given
index :dimensions, :stored_sortable do
crazy_dimensions
end
def crazy_dimensions
"#{height}x#{width}"
end
end
Currently, I basically have to do this:
def to_solr(solr_doc = {})
solr_doc[ActiveFedora::SolrService.solr_name(:dimensions, :stored_sortable)] = crazy_dimensions
end
which (besides being ugly) means that if somewhere else I want to search on that index, have to recalculate the index field name, because it's not actually stored anywhere.
In the proposed code I would be able to get the field name with
Image.index_name(:dimensions) # => "dimensions_ssi"
In response to a desire not to have to put index statements on models, and to extending this capability to properties, I modified it to support multiple "indexers", which can be added like:
class Image < ActiveFedora::Base
index_with ImageIndexer
end
where ImageIndexer
is a subclass of ActiveFedora::Indexer
(a PORO) and contains index statements.
For model-level and property index statements, there is a "default indexer" to which those statements are added.
Indexers are inherited by subclasses and instances via Rails's class_attribute
mechanism.
With all this, when an object has to generate its solr document, it can simply iterate through its indexers, passing itself and collecting all the index name, value pairs.
👍 as someone who's gone down the path of overriding to_solr, this looks like a much better approach.