Sha256: a089ffc3e7d78f7f83e6761b25630f7dea60102985272ba3ac2101a47f7fcdca

Contents?: true

Size: 1.9 KB

Versions: 10

Compression:

Stored size: 1.9 KB

Contents

module Sequel
  module Plugins
    # Sequel by default does not use proxies for associations.  The association
    # method for *_to_many associations returns an array, and the association_dataset
    # method returns a dataset.  This plugin makes the association method return a proxy
    # that will load the association and call a method on the association array if sent
    # an array method, and otherwise send the method to the association's dataset.
    module AssociationProxies
      # A proxy for the association.  Calling an array method will load the
      # associated objects and call the method on the associated object array.
      # Calling any other method will call that method on the association's dataset.
      class AssociationProxy < BasicObject
        # Empty array used to check if an array responds to the given method.
        ARRAY = []

        # Set the association reflection to use, and whether the association should be
        # reloaded if an array method is called.
        def initialize(instance, reflection, reload=nil)
          @instance = instance
          @reflection = reflection
          @reload = reload
        end

        # Call the method given on the array of associated objects if the method
        # is an array method, otherwise call the method on the association's dataset.
        def method_missing(meth, *args, &block)
          (ARRAY.respond_to?(meth) ? @instance.send(:load_associated_objects, @reflection, @reload) : @instance.send(@reflection.dataset_method)).
            send(meth, *args, &block)
        end
      end

      module ClassMethods
        # Changes the association method to return a proxy instead of the associated objects
        # directly.
        def def_association_method(opts)
          opts.returns_array? ? association_module_def(opts.association_method){|*r| AssociationProxy.new(self, opts, r[0])} : super
        end
      end
    end
  end
end

Version data entries

10 entries across 10 versions & 2 rubygems

Version Path
sequel-3.11.0 lib/sequel/plugins/association_proxies.rb
viking-sequel-3.10.0 lib/sequel/plugins/association_proxies.rb
sequel-3.10.0 lib/sequel/plugins/association_proxies.rb
sequel-3.9.0 lib/sequel/plugins/association_proxies.rb
sequel-3.8.0 lib/sequel/plugins/association_proxies.rb
sequel-3.7.0 lib/sequel/plugins/association_proxies.rb
sequel-3.6.0 lib/sequel/plugins/association_proxies.rb
sequel-3.5.0 lib/sequel/plugins/association_proxies.rb
sequel-3.4.0 lib/sequel/plugins/association_proxies.rb
sequel-3.3.0 lib/sequel/plugins/association_proxies.rb