Module: Shamu::Services::LazyAssociation
- Defined in:
- lib/shamu/services/lazy_association.rb
Overview
Lazily look up an associated resource
Constant Summary collapse
- EXCLUDE_PATTERN =
rubocop:disable Metrics/LineLength
/\A(block_given\?|id|send|public_send|iterator|object_id|to_model_id|binding|class|kind_of\?|is_a\?|instance_of\?|respond_to\?|p.+_methods|__.+__)\z/
- MUTEX =
Mutex.new
Class Method Summary collapse
-
.class_for(klass) ⇒ Object
rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity.
Class Method Details
.class_for(klass) ⇒ Object
rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/shamu/services/lazy_association.rb', line 9 def self.class_for( klass ) # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity return klass.const_get( :Lazy_ ) if klass.const_defined?( :Lazy_ ) MUTEX.synchronize do # Check again in case another thread defined it while waiting for the # mutex return klass.const_get( :Lazy_ ) if klass.const_defined?( :Lazy_ ) lazy_class = Class.new( klass ) do # Remove all existing public methods so that they can be delegated # with #method_missing. klass.public_instance_methods.each do |method| next if EXCLUDE_PATTERN =~ method undef_method method end def initialize( id, &block ) @id = id @block = block end # @!attribute # @return [Object] the primary key id of the association. Not delegated so # it is safe to use and will not trigger an unnecessary fetch. attr_reader :id def __getobj__ return @association if defined? @association @association = @block.call( @id ) if @block end def method_missing( method, *args, &block ) if respond_to_missing?( method ) __getobj__.public_send( method, *args, &block ) else super end end def respond_to_missing?( method, include_private = false ) __getobj__.respond_to?( method, include_private ) || super end end klass.const_set( :Lazy_, lazy_class ) lazy_class end end |