Class: Pluckr::Schema::Definition

Inherits:
Object
  • Object
show all
Defined in:
lib/pluckr/schema/definition.rb

Overview

Evaluates the schema do ... end block and builds a Scope of AST nodes.

All validation happens here, at class-definition time, so mistakes blow up when the query is loaded rather than when it is executed.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model) ⇒ Definition

Returns a new instance of Definition.



23
24
25
26
# File 'lib/pluckr/schema/definition.rb', line 23

def initialize(model)
  @model = model
  @nodes = []
end

Class Method Details

.build(model, label: "schema", &block) ⇒ Object

Parameters:

  • model (Class<ActiveRecord::Base>, nil)

    nil for aggregate-only queries

Raises:



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/pluckr/schema/definition.rb', line 11

def self.build(model, label: "schema", &block)
  raise ConfigurationError, "`#{label}` requires a block" unless block

  definition = new(model)
  definition.instance_eval(&block)
  scope = definition.to_scope

  raise ConfigurationError, "`#{label}` block is empty - declare at least one node" if scope.nodes.empty?

  scope
end

Instance Method Details

#avg(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil) ⇒ Object Also known as: average



91
92
93
# File 'lib/pluckr/schema/definition.rb', line 91

def avg(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil)
  aggregate(:avg, name, from: from, via: via, as: as, where: where, column: column, scope: scope)
end

#count(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil) ⇒ Object



83
84
85
# File 'lib/pluckr/schema/definition.rb', line 83

def count(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil)
  aggregate(:count, name, from: from, via: via, as: as, where: where, column: column, scope: scope)
end

#exists(name, via: nil, as: nil, where: nil, scope: nil) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/pluckr/schema/definition.rb', line 69

def exists(name, via: nil, as: nil, where: nil, scope: nil)
  require_source!("exists :#{name}")
  association = Reflection::Association.for(@model, via || name)
  validate_where!(association.klass, where)
  validate_scope!("exists :#{name}", scope)

  add Exists.new(
    output: as || :"#{name}_exists",
    association: association,
    where: where,
    scope: scope
  )
end

#field(name, as: nil) ⇒ Object

---------------------------------------------------------------- DSL --



34
35
36
37
38
# File 'lib/pluckr/schema/definition.rb', line 34

def field(name, as: nil)
  require_source!("field :#{name}")
  validate_column!(@model, name)
  add Field.new(column: name, output: as || name)
end

#first(name, via: nil, order: nil, &block) ⇒ Object

first :comment, via: :comments do ... end - the earliest row of a collection, by primary key unless order: says otherwise.



60
61
62
# File 'lib/pluckr/schema/definition.rb', line 60

def first(name, via: nil, order: nil, &block)
  pick(:first, name, via: via, order: order, &block)
end

#last(name, via: nil, order: nil, &block) ⇒ Object

last :comment, via: :comments, order: :created_at do ... end



65
66
67
# File 'lib/pluckr/schema/definition.rb', line 65

def last(name, via: nil, order: nil, &block)
  pick(:last, name, via: via, order: order, &block)
end

#max(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil) ⇒ Object



100
101
102
# File 'lib/pluckr/schema/definition.rb', line 100

def max(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil)
  aggregate(:max, name, from: from, via: via, as: as, where: where, column: column, scope: scope)
end

#min(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil) ⇒ Object



96
97
98
# File 'lib/pluckr/schema/definition.rb', line 96

def min(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil)
  aggregate(:min, name, from: from, via: via, as: as, where: where, column: column, scope: scope)
end

#one(name, via: nil, &block) ⇒ Object

Raises:



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/pluckr/schema/definition.rb', line 40

def one(name, via: nil, &block)
  require_source!("one :#{name}")
  raise ConfigurationError, "`one :#{name}` requires a block" unless block

  association = Reflection::Association.for(@model, via || name)
  unless association.singular?
    raise InvalidAssociation,
          "`#{@model.name}##{association.name}` is a #{association.macro} association " \
          "and cannot be used with `one`"
  end

  add One.new(
    output: name,
    association: association,
    scope: Definition.build(association.klass, label: "one :#{name}", &block)
  )
end

#sum(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil) ⇒ Object



87
88
89
# File 'lib/pluckr/schema/definition.rb', line 87

def sum(name, from: nil, via: nil, as: nil, where: nil, column: nil, scope: nil)
  aggregate(:sum, name, from: from, via: via, as: as, where: where, column: column, scope: scope)
end

#to_scopeObject



28
29
30
# File 'lib/pluckr/schema/definition.rb', line 28

def to_scope
  Scope.new(@model, @nodes)
end