Module: Shamu::Services::ActiveRecordCrud
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/shamu/services/active_record_crud.rb
Overview
Adds standard CRUD builders to an ActiveRecordService to reduce boilerplate for common methods.
Constant Summary collapse
- DSL_METHODS =
Known DSL methods defined by Shamu::Services::ActiveRecordCrud.
%i[ create update change destroy find list lookup finders crud ].freeze
Class Method Summary collapse
-
.define_build_entities {|records| ... }
Define a private
build_entities( records )
method that constructs an Entities::Entity for each of the givenrecords
. -
.define_change(method, default_scope = model_class) {|request, record, *args| ... } ⇒ Result, void
Define an change
method
on the service that takes the id of the resource to modify and a corresponding Request parameter. -
.define_create {|request, record, *args| ... }
Define a
#create
method on the service that takes a single Request parameter. -
.define_crud ⇒ Object
Define all basic CRUD methods without any customization.
-
.define_destroy(default_scope = model_class) {|request, record, *args| ... }
Define a
destroy( id )
method that takes an Entities::Entity Entities::Entity#id and destroys the resource. -
.define_find(default_scope = model_class.all) {|id| ... }
Define a
find( id )
method on the service that returns the entity with the given id if found or raises a NotFoundError if the entity does not exist. -
.define_finders(default_scope = model_class.all, only: nil, except: nil)
Define the standard finder methods find, lookup and list.
-
.define_list(default_scope = model_class.all) {|scope| ... }
Define a
list( params = nil )
method that takes a Entities::ListScope and returns all the entities selected by that scope. -
.define_lookup(default_scope = model_class.all) {|uncached_ids| ... }
Define a
lookup( *ids )
method that takes a list of entity ids to find. -
.define_update(default_scope = model_class, &block) ⇒ Object
Defines an #update method.
-
.entity_class ⇒ Class
The Entities::Entity class that the service will return from it's methods.
-
.model_class ⇒ Class
The ActiveRecord::Base class used to store the data managed by the service.
-
.resource(entity_class, model_class, methods: nil) {|records| ... }
Declare the entity and resource classes used by the service.
Instance Method Summary collapse
-
#authorize!(method, resource, additional_context = nil) ⇒ resource
Hook to allow a security module to authorize actions taken by the standard CRUD methods.
-
#authorize_relation(method, relation, additional_context = nil) ⇒ relation
Hook to allow a security module to pre-filter ActiveRecord queries for the standard crud methods.
Class Method Details
.define_build_entities {|records| ... }
This method returns an undefined value.
Define a private build_entities( records )
method that
constructs an Entities::Entity for each of the given records
.
If no block is given, creates a simple builder that simply constructs
an instance of the entity_class passing record: record
to the
initializer.
See Service#lookup_association for details on association caching.
343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/shamu/services/active_record_crud.rb', line 343 def define_build_entities( &block ) if block_given? define_method :build_entities, &block else define_method :build_entities do |records| records.map do |record| entity = scorpion.fetch( entity_class, { record: record }, {} ) :read, entity end end end private :build_entities end |
.define_change(method, default_scope = model_class) {|request, record, *args| ... } ⇒ Result, void
Define an change method
on the service that takes the id of the
resource to modify and a corresponding Request parameter.
overridden #with_request method.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/shamu/services/active_record_crud.rb', line 186 def define_change( method, default_scope = model_class, &block ) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/LineLength define_method method do |id, params = nil| klass = request_class( method ) params, id = id, id[ :id ] if !params && !id.respond_to?( :to_model_id ) params[ :id ] ||= id if params with_partial_request params, klass do |request, *args| record = default_scope.find( id.to_model_id || request.id ) entity = build_entity( record ) backfill_attributes = entity.to_attributes( only: request.unassigned_attributes ) request.assign_attributes backfill_attributes next unless request.valid? method, entity, request request.apply_to( record ) if block_given? result = instance_exec record, request, *args, &block next result if result.is_a?( Services::Result ) end next record unless record.save build_entity record end end end |
.define_create {|request, record, *args| ... }
This method returns an undefined value.
Define a #create
method on the service that takes a single Request
parameter.
overridden #with_request method.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/shamu/services/active_record_crud.rb', line 158 def define_create( &block ) define_method :create do |params = nil| with_request params, request_class( :create ) do |request, *args| record = request.apply_to( model_class.new ) if block_given? result = instance_exec record, request, *args, &block next result if result.is_a?( Services::Result ) end :create, build_entity( record ), request next record unless record.save build_entity record end end end |
.define_crud ⇒ Object
Define all basic CRUD methods without any customization.
142 143 144 145 146 147 |
# File 'lib/shamu/services/active_record_crud.rb', line 142 def define_crud define_create define_update define_destroy define_finders end |
.define_destroy(default_scope = model_class) {|request, record, *args| ... }
This method returns an undefined value.
Define a destroy( id )
method that takes an Entities::Entity Entities::Entity#id
and destroys the resource.
overridden #with_request method.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/shamu/services/active_record_crud.rb', line 231 def define_destroy( default_scope = model_class, &block ) define_method :destroy do |params| klass = request_class( :destroy ) params = { id: params } if params.respond_to?( :to_model_id ) with_request params, klass do |request, *args| record = default_scope.find( request.id ) :destroy, build_entity( record ), request instance_exec record, request, *args, &block if block_given? next record unless record.destroy end end end |
.define_find(default_scope = model_class.all) {|id| ... }
This method returns an undefined value.
Define a find( id )
method on the service that returns the entity
with the given id if found or raises a NotFoundError if the
entity does not exist.
270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/shamu/services/active_record_crud.rb', line 270 def define_find( default_scope = model_class.all, &block ) if block_given? define_method :find do |id| wrap_not_found do record = yield( id ) :read, build_entity( record ) end end else define_method :find do |id| :read, find_by_lookup( id ) end end end |
.define_finders(default_scope = model_class.all, only: nil, except: nil)
This method returns an undefined value.
Define the standard finder methods find, lookup and list.
252 253 254 255 256 257 258 259 |
# File 'lib/shamu/services/active_record_crud.rb', line 252 def define_finders( default_scope = model_class.all, only: nil, except: nil ) methods = Array( only || [ :find, :lookup, :list ] ) methods -= Array( except ) if except methods.each do |method| send :"define_#{ method }", default_scope end end |
.define_list(default_scope = model_class.all) {|scope| ... }
This method returns an undefined value.
Define a list( params = nil )
method that takes a
Entities::ListScope and returns all the entities selected by that
scope.
317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/shamu/services/active_record_crud.rb', line 317 def define_list( default_scope = model_class.all, &block ) define_method :list do |params = nil| list_scope = Entities::ListScope.for( entity_class ).coerce( params ) :list, entity_class, list_scope records = block_given? ? yield( scope ) : scope_relation( default_scope, list_scope ) records = ( :read, records, list_scope ) entity_list records end end |
.define_lookup(default_scope = model_class.all) {|uncached_ids| ... }
This method returns an undefined value.
Define a lookup( *ids )
method that takes a list of entity ids to
find. Calls #build_entities to map all found records to entities,
or constructs a Entities::NullEntity for ids that were not found.
297 298 299 300 301 302 303 304 305 |
# File 'lib/shamu/services/active_record_crud.rb', line 297 def define_lookup( default_scope = model_class.all, &block ) define_method :lookup do |*ids| cached_lookup( ids ) do |uncached_ids| records = block_given? ? yield( uncached_ids ) : default_scope.where( id: uncached_ids ) records = :read, records entity_lookup_list records, uncached_ids, entity_class.null_entity end end end |
.define_update(default_scope = model_class, &block) ⇒ Object
Defines an #update method. See #define_change for details.
216 217 218 |
# File 'lib/shamu/services/active_record_crud.rb', line 216 def define_update( default_scope = model_class, &block ) define_change :update, default_scope, &block end |
.entity_class ⇒ Class
The Entities::Entity class that the service will return from it's methods.
131 132 133 |
# File 'lib/shamu/services/active_record_crud.rb', line 131 def entity_class resource_not_configured end |
.model_class ⇒ Class
Returns the ActiveRecord::Base class used to store the data managed by the service.
137 138 139 |
# File 'lib/shamu/services/active_record_crud.rb', line 137 def model_class resource_not_configured end |
.resource(entity_class, model_class, methods: nil) {|records| ... }
This method returns an undefined value.
Declare the entity and resource classes used by the service.
Creates instance and class level methods entity_class
and
model_class
.
See build_entities for build_entities block details.
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/shamu/services/active_record_crud.rb', line 115 def resource( entity_class, model_class, methods: nil, &block ) private define_method( :entity_class ) { entity_class } define_singleton_method( :entity_class ) { entity_class } private define_method( :model_class ) { model_class } define_singleton_method( :model_class ) { model_class } ( Array( methods ) & DSL_METHODS ).each do |method| send :"define_#{ method }" end define_build_entities( &block ) end |
Instance Method Details
#authorize!(method, resource, additional_context = nil) ⇒ resource
Hook to allow a security module to authorize actions taken by the standard CRUD methods. If authorization is not granted, then an exception should be raised. Default behavior is a no-op.
76 77 78 |
# File 'lib/shamu/services/active_record_crud.rb', line 76 def ( method, resource, additional_context = nil ) resource end |
#authorize_relation(method, relation, additional_context = nil) ⇒ relation
Hook to allow a security module to pre-filter ActiveRecord queries for the standard crud methods. Default behavior is a no-op.
91 92 93 |
# File 'lib/shamu/services/active_record_crud.rb', line 91 def ( method, relation, additional_context = nil ) relation end |