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(method = :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(method = :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.
367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/shamu/services/active_record_crud.rb', line 367 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.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/shamu/services/active_record_crud.rb', line 191 def define_change( method, default_scope = model_class, &block ) define_method method do |id, params = nil| klass = request_class( method ) id, params = extract_params( id, 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 ) next unless request.valid? end next record unless record.save build_entity record end end end |
.define_create(method = :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.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/shamu/services/active_record_crud.rb', line 162 def define_create( method = :create, &block ) define_method method do |params = nil| with_request params, request_class( method ) 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 ) next unless request.valid? end method, 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.
146 147 148 149 150 151 |
# File 'lib/shamu/services/active_record_crud.rb', line 146 def define_crud define_create define_update define_destroy define_finders end |
.define_destroy(method = :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.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/shamu/services/active_record_crud.rb', line 236 def define_destroy( method = :destroy, default_scope = model_class, &block ) define_method method do |params| klass = request_class( method ) params = { id: params } if params.respond_to?( :to_model_id ) with_request params, klass do |request, *args| record = default_scope.find( request.id ) method, build_entity( record ), request if block_given? instance_exec record, request, *args, &block next unless request.valid? end 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.
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/shamu/services/active_record_crud.rb', line 279 def define_find( default_scope = model_class.all, &block ) if block_given? define_method :_find_block, &block define_method :find do |id| wrap_not_found do record = _find_block( 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.
261 262 263 264 265 266 267 268 |
# File 'lib/shamu/services/active_record_crud.rb', line 261 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.
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
# File 'lib/shamu/services/active_record_crud.rb', line 335 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 = if block_given? instance_exec( list_scope, &block ) else scope_relation( default_scope, list_scope ) end 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.
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/shamu/services/active_record_crud.rb', line 307 def define_lookup( default_scope = model_class.all, &block ) if block_given? define_method :_lookup_block, &block else define_method :_lookup_block do |ids| default_scope.where( id: ids ) end end define_method :lookup do |*ids| cached_lookup( ids ) do |uncached_ids| records = _lookup_block( 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.
221 222 223 |
# File 'lib/shamu/services/active_record_crud.rb', line 221 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.
135 136 137 |
# File 'lib/shamu/services/active_record_crud.rb', line 135 def entity_class resource_not_configured end |
.model_class ⇒ Class
Returns the ActiveRecord::Base class used to store the data managed by the service.
141 142 143 |
# File 'lib/shamu/services/active_record_crud.rb', line 141 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.
119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/shamu/services/active_record_crud.rb', line 119 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 |