Association

Constants

  • VALID_ASSOCIATION_OPTION_KEYS
  • VALID_REL_LENGTH_SYMBOLS

Methods

#add_destroy_callbacks

def add_destroy_callbacks(model)
  return if dependent.nil?

  model.before_destroy(&method("dependent_#{dependent}_callback"))
rescue NameError
  raise "Unknown dependent option #{dependent}"
end
#arrow_cypher

Return cypher partial query string for the relationship part of a MATCH (arrow / relationship definition)

def arrow_cypher(var = nil, properties = {}, create = false, reverse = false, length = nil)
  validate_origin!

  if create && length.present?
    fail(ArgumentError, 'rel_length option cannot be specified when creating a relationship')
  end

  direction_cypher(get_relationship_cypher(var, properties, create, length), create, reverse)
end

#callback

def callback(type)
  @callbacks[type]
end

#create_method

def create_method
  unique? ? :create_unique : :create
end

#decorated_rel_type

def decorated_rel_type(type)
  @decorated_rel_type ||= Neo4j::Shared::RelTypeConverters.decorated_rel_type(type)
end
#dependent

Returns the value of attribute dependent

def dependent
  @dependent
end

#derive_model_class

def derive_model_class
  refresh_model_class! if pending_model_refresh?
  return @model_class unless @model_class.nil?
  return nil if relationship_class.nil?
  dir_class = direction == :in ? :from_class : :to_class
  return false if relationship_class.send(dir_class).to_s.to_sym == :any
  relationship_class.send(dir_class)
end
#direction

Returns the value of attribute direction

def direction
  @direction
end

#discovered_model

def discovered_model
  target_class_names.map(&:constantize).select do |constant|
    constant.ancestors.include?(::Neo4j::ActiveNode)
  end
end

#initialize

def initialize(type, direction, name, options = {type: nil})
  validate_init_arguments(type, direction, name, options)
  @type = type.to_sym
  @name = name
  @direction = direction.to_sym
  @target_class_name_from_name = name.to_s.classify
  apply_vars_from_options(options)
end

#inject_classname

def inject_classname(properties)
  return properties unless relationship_class
  properties[Neo4j::Config.class_name_property] = relationship_class_name if relationship_class.cached_class?(true)
  properties
end
#model_class

Returns the value of attribute model_class

def model_class
  @model_class
end
#name

Returns the value of attribute name

def name
  @name
end

#pending_model_refresh?

def pending_model_refresh?
  !!@pending_model_refresh
end

#perform_callback

def perform_callback(caller, other_node, type)
  return if callback(type).nil?
  caller.send(callback(type), other_node)
end

#queue_model_refresh!

def queue_model_refresh!
  @pending_model_refresh = true
end

#refresh_model_class!

def refresh_model_class!
  @pending_model_refresh = @target_classes_or_nil = nil

  # Using #to_s on purpose here to take care of classes/strings/symbols
  @model_class = @model_class.to_s.constantize if @model_class
end

#rel_class?

def relationship_class?
  !!relationship_class
end
#relationship

Returns the value of attribute relationship

def relationship
  @relationship
end

#relationship_class

def relationship_class
  @relationship_class ||= @relationship_class_name && @relationship_class_name.constantize
end

#relationship_class?

def relationship_class?
  !!relationship_class
end
#relationship_class_name

Returns the value of attribute relationship_class_name

def relationship_class_name
  @relationship_class_name
end

#relationship_class_type

def relationship_class_type
  relationship_class._type.to_sym
end

#relationship_type

def relationship_type(create = false)
  case
  when relationship_class
    relationship_class_type
  when !@relationship_type.nil?
    @relationship_type
  when @origin
    origin_type
  else
    (create || exceptional_target_class?) && decorated_rel_type(@name)
  end
end

#target_class

def target_class
  return @target_class if @target_class

  @target_class = target_class_names[0].constantize if target_class_names && target_class_names.size == 1
rescue NameError
  raise ArgumentError, "Could not find `#{@target_class}` class and no :model_class specified"
end

#target_class_names

def target_class_names
  option = target_class_option(derive_model_class)

  @target_class_names ||= if option.is_a?(Array)
                            option.map(&:to_s)
                          elsif option
                            [option.to_s]
                          end
end

#target_class_option

def target_class_option(model_class)
  case model_class
  when nil
    @target_class_name_from_name ? "#{association_model_namespace}::#{@target_class_name_from_name}" : @target_class_name_from_name
  when Array
    model_class.map { |sub_model_class| target_class_option(sub_model_class) }
  when false
    false
  else
    model_class.to_s[0, 2] == '::' ? model_class.to_s : "::#{model_class}"
  end
end

#target_classes

def target_classes
  target_class_names.map(&:constantize)
end

#target_classes_or_nil

def target_classes_or_nil
  @target_classes_or_nil ||= discovered_model if target_class_names
end

#target_where_clause

def target_where_clause
  return if model_class == false

  Array.new(target_classes).map do |target_class|
    "#{name}:#{target_class.mapped_label_name}"
  end.join(' OR ')
end
#type

Returns the value of attribute type

def type
  @type
end

#unique?

def unique?
  return relationship_class.unique? if rel_class?
  @origin ? origin_association.unique? : !!@unique
end

#validate_dependent

def validate_dependent(value)
  fail ArgumentError, "Invalid dependent value: #{value.inspect}" if not valid_dependent_value?(value)
end