Class: Hoodoo::ActiveRecord::Support

Inherits:
Object
  • Object
show all
Defined in:
lib/hoodoo/active/active_record/support.rb

Overview

Most of the ActiveRecord support code provides mixins with a public API. That public interface makes it obvious what the mixin’s defined method names will be, helping to avoid collisions/shadowing. Sometimes, those methods want to share code but private methods don’t work well in that context - their names could unwittingly collide with names in the including class, written by an author not aware of those essentially hidden but vital interfaces.

This is a support class specifically designed to solve this issue. It’s really a public, independent expression of a series of specialised methods that would otherwise have normally been private.

Although this code forms part of the Hoodoo public API, its unusual status means that you should not really call any of these methods unless you’re prepared to track unexpected API changes in them in future and update your calling code.

Class Method Summary collapse

Class Method Details

.add_undated_scope_to(base_scope, klass, context) ⇒ Object

Back-end of sorts for ::full_scope_for. Given a base scope (e.g. ‘Model.all’), applies all available appropriate scoping additions included by that model, such as Hoodoo::ActiveRecord::Secure and Hoodoo::ActiveRecord::Translated, except for the dating modules Hoodoo::ActiveRecord::Dated and Hoodoo::ActiveRecord::ManuallyDated.

If you wish to use dating as well, call ::full_scope_for instead.

base_scope

The ActiveRecord::Relation instance providing the base scope to which additions will be made.

klass

The ActiveRecord::Base subclass class (not instance) which is making the call here. This is the entity which is checked for module inclusions to determine how the query chain should be assembled.

context

Hoodoo::Services::Context instance describing a call context. This is typically a value passed to one of the Hoodoo::Services::Implementation instance methods that a resource subclass implements.

Returns the given input scope, with additional conditions added for any Hoodoo ActiveRecord extension modules included by the ActiveRecord model class that the scope targets.



174
175
176
177
178
179
180
181
182
183
184
# File 'lib/hoodoo/active/active_record/support.rb', line 174

def self.add_undated_scope_to( base_scope, klass, context )
  if klass.include?( Hoodoo::ActiveRecord::Secure )
    base_scope = base_scope.secure( context )
  end

  if klass.include?( Hoodoo::ActiveRecord::Translated )
    base_scope = base_scope.translated( context )
  end

  return base_scope
end

.framework_search_and_filter_dataObject

Returns a (newly generated) Hash of search keys mapping to helper Procs which are in the same format as would be passed to Hoodoo::ActiveRecord::Finder::ClassMethods#search_with or Hoodoo::ActiveRecord::Finder::ClassMethods#filter_with, describing the default framework search parameters. The middleware defines keys, but each ORM adapter module must specify how those keys actually get used to search inside supported database engines.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/hoodoo/active/active_record/support.rb', line 46

def self.framework_search_and_filter_data

  # The middleware includes framework-level mappings between URI query
  # string search keys and data validators and processors which convert
  # types where necessary. For example, 'created_at' must be given a
  # valid ISO 8601 subset string and a parsed DateTime will end up in
  # the parsed search hash.
  #
  # Services opt out of framework-level searching at an interface level
  # which means the Finder code herein, under normal flow, will never
  # be asked to process something the interface omits. There is thus no
  # need to try and break encapsulation and come up with a way to read
  # the service interface's omissions. Instead, map everything.
  #
  # This could actually be useful if someone manually drives the #list
  # mechanism with hand-constructed search or filter data that quite
  # intentionally includes framework level parameters even if their own
  # service interface for some reason opts out of allowing them to be
  # exposed to API callers.
  #
  # Note that the #search_with / #filter_with DSL declaration in an
  # appropriately extended model can be used to override the default
  # values wired in below, because the defaults are established by
  # design _before_ the model declarations are processed.
  #
  mapping = {
    'created_after'  => Hoodoo::ActiveRecord::Finder::SearchHelper.cs_gt( :created_at ),
    'created_before' => Hoodoo::ActiveRecord::Finder::SearchHelper.cs_lt( :created_at ),
    'created_by'     => Hoodoo::ActiveRecord::Finder::SearchHelper.cs_match( :created_by )
  }

  if mapping.keys.length != ( mapping.keys | Hoodoo::Services::Middleware::FRAMEWORK_QUERY_DATA.keys ).length
    raise 'Hoodoo::ActiveRecord::Support#framework_search_and_filter_data: Mismatch between internal mapping and Hoodoo::Services::Middleware::FRAMEWORK_QUERY_DATA'
  end

  return mapping
end

.full_scope_for(klass, context) ⇒ Object

Given an ActiveRecord class and Hoodoo request context, work out which Hoodoo support modules are included within this class and call base methods to provide a fully specified basic query chain obeying all the necessary aspects of the ActiveRecord model class and the request.

Each of the following are called if the owning module is included:

  • Hoodoo::ActiveRecord::Secure#secure

  • Hoodoo::ActiveRecord::Translated#translated

  • Hoodoo::ActiveRecord::Dated#dated (if “dating_enabled?” is true)

  • Hoodoo::ActiveRecord::ManuallyDated#manually_dated (if “manual_dating_enabled?” is true)

klass

The ActiveRecord::Base subclass class (not instance) which is making the call here. This is the entity which is checked for module inclusions to determine how the query chain should be assembled.

context

Hoodoo::Services::Context instance describing a call context. This is typically a value passed to one of the Hoodoo::Services::Implementation instance methods that a resource subclass implements.

Returns an ActiveRecord::Relation instance which is anything from a generic anonymous scope, all the way through to a secured, translated, backdated scope for use with subsequent query refinements.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/hoodoo/active/active_record/support.rb', line 132

def self.full_scope_for( klass, context )
  prevailing_scope = klass.all() # "Model.all" -> returns anonymous scope

  # Due to the mechanism used, dating scope must be done first or the
  # rest of the query may be invalid.
  #
  if klass.include?( Hoodoo::ActiveRecord::Dated ) && klass.dating_enabled?()
    prevailing_scope = prevailing_scope.dated( context )
  end

  if klass.include?( Hoodoo::ActiveRecord::ManuallyDated ) && klass.manual_dating_enabled?()
    prevailing_scope = prevailing_scope.manually_dated( context )
  end

  return self.add_undated_scope_to( prevailing_scope, klass, context )
end

.process_to_map(hash) ⇒ Object

Takes a Hash of possibly-non-String keys and with nil values or Proc instances appropriate for Hoodoo::ActiveRecord::Finder::ClassMethods#search_with / Hoodoo::ActiveRecord::Finder::ClassMethods#filter_with. Returns a similar Hash with all-String keys and a Proc for every value.

hash

Hash Symbol or String keys and Proc instance or nil values.



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/hoodoo/active/active_record/support.rb', line 93

def self.process_to_map( hash )
  map = Hoodoo::Utilities.stringify( hash )

  map.each do | attr, proc_or_nil |
    if proc_or_nil.nil?
      map[ attr ] = Hoodoo::ActiveRecord::Finder::SearchHelper.cs_match( attr )
    end
  end

  return map
end