Class: NoBrainer::Document::Association::HasMany::Metadata

Inherits:
Object
  • Object
show all
Includes:
Core::Metadata, EagerLoader::Generic
Defined in:
lib/no_brainer/document/association/has_many.rb

Constant Summary collapse

VALID_OPTIONS =
[:primary_key, :foreign_key, :class_name, :dependent, :scope,
:as]

Instance Attribute Summary

Attributes included from Core::Metadata

#options, #owner_model, #target_name

Instance Method Summary collapse

Methods included from EagerLoader::Generic

#eager_load

Methods included from Core::Metadata

#add_callback_for, #association_model, #delegate, #get_model_by_name, #initialize, #new

Instance Method Details

#base_criteriaObject



29
30
31
# File 'lib/no_brainer/document/association/has_many.rb', line 29

def base_criteria
  options[:scope] ? target_model.instance_exec(&options[:scope]) : target_model.all
end

#eager_load_owner_keyObject



64
# File 'lib/no_brainer/document/association/has_many.rb', line 64

def eager_load_owner_key;  primary_key; end

#eager_load_owner_typeObject



65
# File 'lib/no_brainer/document/association/has_many.rb', line 65

def eager_load_owner_type; foreign_type; end

#eager_load_target_keyObject



66
# File 'lib/no_brainer/document/association/has_many.rb', line 66

def eager_load_target_key; foreign_key; end

#foreign_keyObject



10
11
12
13
14
15
# File 'lib/no_brainer/document/association/has_many.rb', line 10

def foreign_key
  return options[:foreign_key].try(:to_sym) if options.key?(:foreign_key)
  return :"#{options[:as]}_#{primary_key}" if options[:as]

  :"#{owner_model.name.split('::').last.underscore}_#{primary_key}"
end

#foreign_typeObject



17
18
19
# File 'lib/no_brainer/document/association/has_many.rb', line 17

def foreign_type
  options[:foreign_type].try(:to_sym) || (options[:as] && :"#{options[:as]}_type")
end

#hookObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/no_brainer/document/association/has_many.rb', line 47

def hook
  super

  if options[:scope]
    raise ":scope must be passed a lambda like this: `:scope => ->{ where(...) }'" unless options[:scope].is_a?(Proc)
    raise ":dependent and :scope cannot be used together" if options[:dependent]
  end

  if options[:dependent]
    unless [:destroy, :delete, :nullify, :restrict, nil].include?(options[:dependent])
      raise "Invalid dependent option: `#{options[:dependent].inspect}'. " \
            "Valid options are: :destroy, :delete, :nullify, or :restrict"
    end
    add_callback_for(:before_destroy)
  end
end

#inversesObject



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/no_brainer/document/association/has_many.rb', line 33

def inverses
  # We can always infer the inverse association of a has_many relationship,
  # because a belongs_to association cannot have a scope applied on the
  # selector.
  # XXX Without caching, this is going to get CPU intensive quickly, but
  # caching is hard (rails console reload, etc.).
  target_model..values.select do |assoc|
    assoc.is_a?(NoBrainer::Document::Association::BelongsTo::Metadata) and
    assoc.foreign_key == foreign_key                                   and
    assoc.primary_key == primary_key                                   and
    assoc.target_model(target_model).root_class == owner_model.root_class
  end
end

#primary_keyObject



21
22
23
# File 'lib/no_brainer/document/association/has_many.rb', line 21

def primary_key
  options[:primary_key].try(:to_sym) || owner_model.pk_name
end

#target_modelObject



25
26
27
# File 'lib/no_brainer/document/association/has_many.rb', line 25

def target_model
  get_model_by_name(options[:class_name] || target_name.to_s.singularize.camelize)
end