Module: Kithe::Indexer::ObjExtract
- Included in:
- Kithe::Indexer
- Defined in:
- app/indexing/kithe/indexer/obj_extract.rb
Overview
A traject indexer macro that provides an indexing macro to extract values from ruby objects (such as ActiveRecord models, although it does not need to be).
You supply a list of method names, which will be called in turn on the source object and previous results. Each result can be a single object or an array of objects. results are always “collected” when there are multiple results.
For instance, if you have something that looks like this:
my_obj. = [ Author.new(first: "joe", last: "smith"), Author.new(first: "mary", last: "jones")]
You index as:
to_field, "author_first", obj_extract("authors", "first")
And get ‘[“joe”, “mary”]` indexed. Method chains “short circuit” safely on nil, so if the source object has a nil `authors`, no error will be raised, and you’ll simply have no extracted values as expected.
In addition to method calls, if an extracted object in the chain is a Hash, a path key given can be a hash key.
For instance, if you had an object such that you could access something like:
source_record..collect(&:name_hash).collect { |hash| hash["first"] }
You could have a traject indexing file that might look like:
to_field("author_first"), obj_dig("authors", "name", "first")
If your path lookup does not end in strings, you may have non-string objects in the traject accumulator. Since most writers at the end of the traject chain expect strings, you may want to use subsequent transformation steps to transform those objects into strings with custom logic.
FUTURE: Should we extract this to traject itself? Not sure if we’ll end up putting kithe-tied func in here, or how generalizable it is.
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.obj_extractor(obj, path) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'app/indexing/kithe/indexer/obj_extract.rb', line 45 def self.obj_extractor(obj, path) first, *rest = *path result = if obj.kind_of?(Array) obj.flat_map {|item| obj_extractor(item, path)} elsif obj.kind_of?(Hash) obj[first] else obj.send(first) end if result.nil? || rest.empty? result else # recurse obj_extractor(result, rest) end end |
Instance Method Details
#obj_extract(*path) ⇒ Object
39 40 41 42 43 |
# File 'app/indexing/kithe/indexer/obj_extract.rb', line 39 def obj_extract(*path) proc do |record, accumulator, context| accumulator.concat Array.wrap(Kithe::Indexer::ObjExtract.obj_extractor(record, path)) end end |