Class: Shamu::Services::Service
- Inherits:
-
Object
- Object
- Shamu::Services::Service
- Includes:
- Scorpion::Object
- Defined in:
- lib/shamu/services/service.rb
Overview
...
Well Known Methos
list( list_scope ) - lists all of the entities matching the requested list scope. Often apply Entities::ListScope::Paging or other filters.
def list( list_scope ) list_scope = UserListScope.coerce! list_scope entity_list Models::User.by_list_scope( list_scope ) do |record| scorpion.fetch UserEntity, record: record end end
lookup( *ids ) - matches a given list of ids to their entities or a Entities::NullEntity for ids that can't be found. The
lookup
method is typically used to resolve related resources between services - similar to associations in an ActiveRecord model. Use #entity_lookup_list to transform a list of records or external resources to a lookup list of entities.def lookup( *ids ) entity_lookup_list Models::User.where( id: ids ), ids, NullEntity.for( UserEntity ) do |record| scorpion.fetch UserEntity, record: record end end
find( id ) - finds a single entity with the given id, raising NotFoundError if the resource cannot be found. If the service also implements
lookup
then this can be implemented by simply aliasingfind
to #find_by_lookup.def find( id ) find_by_lookup( id ) end
report( report_scope ) - Compile a report including metrics, and master/detail data that make take longer to gather than a standard
list
request.def report( report_scope = nil ) report_scope = UserReportScope.coerce! report_scope scorpion.fetch UserReport, report_scope, {} end
Direct Known Subclasses
Auditing::AuditingService, Auditing::NullAuditingService, Entities::EntityLookupService, Events::EventsService, Features::ConfigService, Features::EnvStore, Features::FeaturesService, Shamu::Sessions::CookieStore
Instance Method Summary collapse
-
#cache_for(key: :id, entity: nil, coerce: :not_set) ⇒ Entities::IdentityCache
Get the Entities::IdentityCache for the given Entities::Entity class.
-
#cached_lookup(ids, match: :id, coerce: :not_set, entity: nil) {|missing_ids| ... } ⇒ Object
Caches the results of looking up the given ids in an Entities::IdentityCache and only fetches the records that have not yet been cached.
-
#entity_list(records) {|record| ... } ⇒ Entities::List
Takes a raw enumerable list of records and transforms them to a proper Entities::List.
-
#entity_lookup_list(records, ids, null_class, match: :id, coerce: :not_set) {|record| ... } ⇒ Entities::List
Match a list of records with the ids used to look up those records.
-
#error(attribute, message) ⇒ ErrorResult
Return an error #result from a service request.
-
#find_by_lookup(id) ⇒ Entities::Entity
For services that expose a standard
lookup
method, find_by_lookup looks up a single entity and raises NotFoundError if the entity is nil or a Entities::NullEntity. -
#lazy_association(id, service, &block) ⇒ LazyAssociation<Entity>
Perform a lazy #lookup_association and only load the entity if its actually dereferenced by the caller.
-
#lookup_association(id, service, &block) ⇒ Entity
Find an associated entity from a dependent service.
Instance Method Details
#cache_for(key: :id, entity: nil, coerce: :not_set) ⇒ Entities::IdentityCache
Get the Entities::IdentityCache for the given Entities::Entity class.
278 279 280 281 282 283 284 |
# File 'lib/shamu/services/service.rb', line 278 def cache_for( key: :id, entity: nil, coerce: :not_set ) coerce = coerce_method( coerce, key ) cache_key = [ entity, key, coerce ] @entity_caches ||= {} @entity_caches[ cache_key ] ||= scorpion.fetch( Entities::IdentityCache, coerce ) end |
#cached_lookup(ids, match: :id, coerce: :not_set, entity: nil) {|missing_ids| ... } ⇒ Object
Caches the results of looking up the given ids in an Entities::IdentityCache and only fetches the records that have not yet been cached.
304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/shamu/services/service.rb', line 304 def cached_lookup( ids, match: :id, coerce: :not_set, entity: nil, &lookup ) coerce = coerce_method( coerce, match ) ids = ids.map( &coerce ) if coerce cache = cache_for( key: match, coerce: coerce, entity: entity ) missing_ids = cache.uncached_keys( ids ) cache_entities( cache, match, missing_ids, &lookup ) if missing_ids.any? entities = ids.map { |id| cache.fetch( id ) || fail( Shamu::NotFoundError ) } Entities::List.new( entities ) end |
#entity_list(records) {|record| ... } ⇒ Entities::List
Takes a raw enumerable list of records and transforms them to a proper Entities::List.
As simple as the method is, it also serves as a hook for mixins to add additional behavior when processing lists.
If a block is not provided, looks for a method build_entities(
records )
that maps a set of records to their corresponding
entities.
96 97 98 99 100 101 102 103 104 |
# File 'lib/shamu/services/service.rb', line 96 def entity_list( records, &transformer ) return Entities::List.new [] unless records unless transformer fail "Either provide a block or add a private method `def build_entities( records )` to #{ self.class.name }." unless respond_to?( :build_entities, true ) # rubocop:disable Metrics/LineLength transformer ||= method( :build_entities ) end build_entity_list build_records_transform( records, &transformer ) end |
#entity_lookup_list(records, ids, null_class, match: :id, coerce: :not_set) {|record| ... } ⇒ Entities::List
Match a list of records with the ids used to look up those records. Uses a Entities::NullEntity if the id doesn't have a matching record.
158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/shamu/services/service.rb', line 158 def entity_lookup_list( records, ids, null_class, match: :id, coerce: :not_set, &transformer ) matcher = entity_lookup_list_matcher( match ) coerce = coerce_method( coerce, match ) ids = ids.map( &coerce ) if coerce list = entity_list records, &transformer matched = ids.map do |id| list.find { |e| matcher.call( e ) == id } || scorpion.fetch( null_class, { id: id }, {} ) end Entities::List.new( matched ) end |
#error(attribute, message) ⇒ ErrorResult
Return an error #result from a service request.
337 338 339 340 341 |
# File 'lib/shamu/services/service.rb', line 337 def error( *args ) Result.new.tap do |r| r.errors.add( *args ) end end |
#find_by_lookup(id) ⇒ Entities::Entity
For services that expose a standard lookup
method, find_by_lookup
looks up a single entity and raises NotFoundError if the
entity is nil or a Entities::NullEntity.
A find
method can then be implemented in terms of the lookup
method.
209 210 211 212 213 |
# File 'lib/shamu/services/service.rb', line 209 def find_by_lookup( id ) entity = lookup( id ).first raise Shamu::NotFoundError unless entity.present? entity end |
#lazy_association(id, service, &block) ⇒ LazyAssociation<Entity>
Perform a lazy #lookup_association and only load the entity if its actually dereferenced by the caller.
261 262 263 264 265 |
# File 'lib/shamu/services/service.rb', line 261 def lazy_association( id, service, &block ) LazyAssociation.new( id ) do lookup_association id, service, &block end end |
#lookup_association(id, service, &block) ⇒ Entity
Find an associated entity from a dependent service. Attempts to efficiently handle multiple requests to lookup associations by caching all the associated entities when #lookup_association is used repeatedly when building an entity.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/shamu/services/service.rb', line 236 def lookup_association( id, service, &block ) return unless id cache = cache_for( entity: service ) cache.fetch( id ) || begin if block_given? && ( ids = yield ) service.lookup( *ids ).map do |entity| cache.add( entity.id, entity ) end cache.fetch( id ) else association = service.lookup( id ).first cache.add( association.id, association ) end end end |