class SmartCollection::Mixin

Attributes

config[R]

Public Class Methods

new(raw_config) click to toggle source
# File lib/smart_collection/mixin.rb, line 13
def initialize raw_config
  @raw_config = raw_config
end

Public Instance Methods

cached_scope(owner) click to toggle source
# File lib/smart_collection/mixin.rb, line 36
def cached_scope owner
  @config.cache_manager.read_scope owner
end
define_association(base) click to toggle source
# File lib/smart_collection/mixin.rb, line 40
def define_association base
  config = @config
  config.cache_manager = CacheManager.new(model: base, config: config)

  mixin_options = {
    name: config.items_name,
    scope: -> owner {
      if owner.new_record?
        uncached_scope(owner)
      else
        cache_manager = config.cache_manager
        unless cache_manager.cache_exists? owner
          owner.update_cache
        end
        cached_scope(owner)
      end
    },
    type: :collection
  }

  cached_name = "cached_#{config.items_name}".to_sym
  mixin_options[:preloader] = -> owners {
    owners.reject(&:cache_exists?).each(&:update_cache)
    Associationist.preload(owners, cached_items: config.item_name)
    owners.map do |owner|
      [owner, owner.cached_items.map{|item| item.send(config.item_name)}]
    end.to_h
  }

  base.include Associationist::Mixin.new(mixin_options)
end
define_inverse_association(base) click to toggle source
# File lib/smart_collection/mixin.rb, line 76
def define_inverse_association base
  return unless @config.inverse_association

  mixin_options = {
    name: @config.inverse_association,
    scope: -> owner {
      expired = base.joins(:cached_items).where(@config.cache_table_name => {item_id: owner.id}).merge(expired_scope base)
      expired.each(&:update_cache)
      base.joins(:cached_items).where(@config.cache_table_name => {item_id: owner.id})
    },
    type: :collection
  }
  @config.item_class.include Associationist::Mixin.new(mixin_options)
end
expired_scope(base) click to toggle source
# File lib/smart_collection/mixin.rb, line 72
def expired_scope base
  base.where(base.arel_table[:cache_expires_at].lt(Time.now))
end
included(base) click to toggle source
# File lib/smart_collection/mixin.rb, line 91
def included base
  @config = config = SmartCollection::Config.new(@raw_config)

  base.include(InstanceMethods)
  base.extend(ClassMethods)

  define_association base
  define_inverse_association base
end
uncached_scope(owner) click to toggle source
# File lib/smart_collection/mixin.rb, line 17
def uncached_scope owner
  scopes = @config.scopes_proc.(owner)
  raise unless scopes.all?{|x| x.klass == @config.item_class}
  if scopes.empty?
    @config.item_class.where('1 = 0')
  else
    scopes = scopes.map do |scope|
      if !scope.select_values.empty?
        new_scope = scope.dup
        new_scope.select_values = []
        new_scope
      else
        scope
      end
    end
    @config.item_class.from("(#{scopes.map{|x| "#{x.to_sql}"}.join(' UNION ')}) as #{@config.item_class.table_name}")
  end
end