Class: ActiveCypher::Relation

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/active_cypher/relation.rb

Overview

Chainable, lazily evaluated Cypher query. Because what you really want is to pretend your database is just a big Ruby array.

Direct Known Subclasses

Associations::CollectionProxy

Constant Summary collapse

LOAD_METHODS =

Methods that trigger query execution Because nothing says “performance” like loading everything at once.

i[each to_a first last count size length any? empty?].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model_class, cyrel_query = nil) ⇒ Relation


Construction


Initializes a Relation. Because direct SQL was too mainstream.

Parameters:

  • model_class (Class)

    The model class for the relation

  • cyrel_query (Object, nil) (defaults to: nil)

    The Cyrel query object



23
24
25
26
27
# File 'lib/active_cypher/relation.rb', line 23

def initialize(model_class, cyrel_query = nil)
  @model_class = model_class
  @cyrel_query = cyrel_query || default_query
  @records     = nil
end

Instance Attribute Details

#cyrel_queryObject (readonly)

Returns the value of attribute cyrel_query.



11
12
13
# File 'lib/active_cypher/relation.rb', line 11

def cyrel_query
  @cyrel_query
end

#model_classObject (readonly)

Returns the value of attribute model_class.



11
12
13
# File 'lib/active_cypher/relation.rb', line 11

def model_class
  @model_class
end

Instance Method Details

#countInteger Also known as: size, length

Counting records: the only math most devs trust.

Returns:

  • (Integer)

    The number of records



103
104
105
106
# File 'lib/active_cypher/relation.rb', line 103

def count
  load_records unless loaded?
  @records.count
end

#each {|record| ... } ⇒ Object


Enumerable / loader


Pretend this is just an array. Your database will never know.

Yields:

  • (record)

    Yields each record in the relation



82
83
84
85
# File 'lib/active_cypher/relation.rb', line 82

def each(&)
  load_records unless loaded?
  @records.each(&)
end

#firstObject?

Because everyone wants to be first.

Returns:

  • (Object, nil)

    The first record



89
90
91
92
# File 'lib/active_cypher/relation.rb', line 89

def first
  load_records unless loaded?
  @records.first
end

#lastObject?

Or last, if you’re feeling dramatic.

Returns:

  • (Object, nil)

    The last record



96
97
98
99
# File 'lib/active_cypher/relation.rb', line 96

def last
  load_records unless loaded?
  @records.last
end

#limit(value) ⇒ Relation

Because sometimes you want less data, but never less abstraction.

Parameters:

  • value (Integer)

    The limit value

Returns:



59
60
61
# File 'lib/active_cypher/relation.rb', line 59

def limit(value)
  spawn(@cyrel_query.clone.limit(value))
end

#loaded?Boolean

Checks if we’ve already loaded the records, or if we’re still living in denial.

Returns:

  • (Boolean)


116
117
118
# File 'lib/active_cypher/relation.rb', line 116

def loaded?
  !@records.nil?
end

#merge(_other) ⇒ Relation

Merges another relation, because why not double the confusion.

Parameters:

Returns:



73
74
75
# File 'lib/active_cypher/relation.rb', line 73

def merge(_other)
  spawn(@cyrel_query.clone)
end

#order(*_args) ⇒ Relation

ORDER support: coming soon, like your next vacation.

Returns:



65
66
67
68
# File 'lib/active_cypher/relation.rb', line 65

def order(*_args)
  # TODO: Implement proper ORDER support
  spawn(@cyrel_query)
end

#reset!void

This method returns an undefined value.

Resets the loaded records, for when you want to pretend nothing ever happened.



122
123
124
# File 'lib/active_cypher/relation.rb', line 122

def reset!
  @records = nil
end

#where(conditions) ⇒ Relation


Query‑builder helpers


Because chaining methods is more fun than writing actual queries.

Parameters:

Returns:

  • (Relation)

    A new relation with the where clause applied



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/active_cypher/relation.rb', line 35

def where(conditions)
  new_query = @cyrel_query.clone
  node_alias = :n

  case conditions
  when Hash
    conditions.each do |key, value|
      expr      = Cyrel.prop(node_alias, key).eq(value)
      new_query = new_query.where(expr)
    end
  when Cyrel::Expression::Base
    new_query = new_query.where(conditions)
  else
    raise ArgumentError,
          "Unsupported type for #where: #{conditions.class}. " \
          'Pass a Hash or Cyrel::Expression.'
  end

  spawn(new_query)
end