Module: SqlAttributes

Defined in:
lib/sql_attributes.rb,
lib/sql_attributes/version.rb

Defined Under Namespace

Classes: NotDefined, NotLoaded

Constant Summary collapse

VERSION =
'1.0.0'

Instance Method Summary collapse

Instance Method Details

#sql_attribute(name, subquery) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/sql_attributes.rb', line 29

def sql_attribute(name, subquery)
  sql_attributes[name] = subquery.squish

  scope "with_#{name}".to_sym, lambda {
    select(
      arel.projections,
      "(#{subquery.squish}) as #{name}"
    )
  }

  define_method(name) do
    return read_attribute(name) if has_attribute?(name)

    raise NotLoaded, <<~MESSAGE
      Dynamic SQL attribute `#{name}` not loaded from the database.

        Use the `with_sql_attributes` scope to load the attribute.

    MESSAGE
  end
end

#sql_attributesObject



8
9
10
# File 'lib/sql_attributes.rb', line 8

def sql_attributes
  @sql_attributes ||= HashWithIndifferentAccess.new
end

#with_sql_attributes(*attributes) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/sql_attributes.rb', line 12

def with_sql_attributes(*attributes)
  requested_attributes =
    if attributes.length.positive?
      Array.wrap(attributes).flatten.reject(&:nil?)
    else
      sql_attributes.keys
    end

  requested_attributes.inject(all) do |scope, name|
    unless sql_attributes.key?(name)
      raise NotDefined, "You want to load dynamic SQL attribute `#{name}` but it is not defined."
    end

    scope.public_send("with_#{name}")
  end
end