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



111
112
113
114
# File 'lib/active_cypher/relation.rb', line 111

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



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

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

#firstObject?

Because everyone wants to be first.

Returns:

  • (Object, nil)

    The first record



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

def first
  load_records unless loaded?
  @records.first
end

#lastObject?

Or last, if you’re feeling dramatic.

Returns:

  • (Object, nil)

    The last record



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

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:



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

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)


124
125
126
# File 'lib/active_cypher/relation.rb', line 124

def loaded?
  !@records.nil?
end

#merge(_other) ⇒ Relation

Merges another relation, because why not double the confusion.

Parameters:

Returns:



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

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

#order(*_args) ⇒ Relation

ORDER support: coming soon, like your next vacation.

Returns:



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

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.



130
131
132
# File 'lib/active_cypher/relation.rb', line 130

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
55
56
57
58
59
60
61
62
# 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|
      if value.is_a?(Array)
        expr      = Cyrel::Expression::Comparison.new(
                      Cyrel.prop(node_alias, key),
                      :IN,
                      value
                    )
      else
        expr      = Cyrel.prop(node_alias, key).eq(value)
      end
      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