Class: Torque::PostgreSQL::Attributes::EnumSet

Inherits:
Set
  • Object
show all
Extended by:
Enumerable
Includes:
Comparable
Defined in:
lib/torque/postgresql/attributes/enum_set.rb

Defined Under Namespace

Classes: EnumSetError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*values) ⇒ EnumSet

Override string initializer to check for a valid value



99
100
101
102
103
104
105
106
107
108
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 99

def initialize(*values)
  items =
    if values.size === 1 && values.first.is_a?(Numeric)
      transform_power(values.first)
    else
      transform_values(values)
    end

  @hash = items.zip(Array.new(items.size, true)).to_h
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *arguments) ⇒ Object (private)

Allow ‘_’ to be associated to ‘-’



217
218
219
220
221
222
223
224
225
226
227
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 217

def method_missing(method_name, *arguments)
  name = method_name.to_s

  if name.chomp!('?')
    include?(name)
  elsif name.chomp!('!')
    add(name) unless include?(name)
  else
    super
  end
end

Class Method Details

.enum_sourceObject

The original Enum implementation, for individual values



40
41
42
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 40

def enum_source
  const_get('EnumSource')
end

.fetch(value) ⇒ Object Also known as: []



63
64
65
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 63

def fetch(value, *)
  new(value.to_s) if values.include?(value)
end

.include_on(klass, method_name = nil) ⇒ Object

Provide a method on the given class to setup which enum sets will be manually initialized



32
33
34
35
36
37
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 32

def include_on(klass, method_name = nil)
  method_name ||= Torque::PostgreSQL.config.enum.set_method
  Builder.include_on(klass, method_name, Builder::Enum, set_features: true) do |builder|
    defined_enums[builder.attribute.to_s] = builder.subtype
  end
end

.lookup(name, enum_klass) ⇒ Object

Find or create the class that will handle the value



19
20
21
22
23
24
25
26
27
28
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 19

def lookup(name, enum_klass)
  const     = name.to_s.camelize + 'Set'
  namespace = Torque::PostgreSQL.config.enum.namespace

  return namespace.const_get(const) if namespace.const_defined?(const)

  klass = Class.new(EnumSet)
  klass.const_set('EnumSource', enum_klass)
  namespace.const_set(const, klass)
end

.new(*values) ⇒ Object

Overpass new so blank values return only nil



50
51
52
53
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 50

def new(*values)
  return Lazy.new(self, []) if values.compact.blank?
  super
end

.power(*values) ⇒ Object

Get the power, 2 ** index, of each element



69
70
71
72
73
74
75
76
77
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 69

def power(*values)
  values.flatten.map do |item|
    item = item.to_i if item.is_a?(Enum)
    item = values.index(item) unless item.is_a?(Numeric)

    next 0 if item.nil? || item >= size
    2 ** item
  end.reduce(:+)
end

.sampleObject

Use the power to get a sample of the value



45
46
47
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 45

def sample
  new(rand(0..((2 ** size) - 1)))
end

.scope(attribute, value) ⇒ Object

Build an active record scope for a given atribute agains a value



80
81
82
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 80

def scope(attribute, value)
  attribute.contains(::Arel.array(value, cast: enum_source.type_name))
end

.type_nameObject

Get the type name from its class name



56
57
58
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 56

def type_name
  @type_name ||= enum_source.type_name + '[]'
end

Instance Method Details

#&(other) ⇒ Object

Override bitwise & operator to ensure formatted values



163
164
165
166
167
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 163

def &(other)
  other = other.entries.map(&method(:instantiate))
  values = @hash.keys.select { |k| other.include?(k) }
  self.class.new(values)
end

#<=>(other) ⇒ Object

Allow comparison between values of the same enum



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 111

def <=>(other)
  raise_comparison(other) if other.is_a?(EnumSet) && other.class != self.class

  to_i <=>
    case other
    when Numeric, EnumSet then other.to_i
    when String, Symbol   then self.class.power(other.to_s)
    when Array, Set       then self.class.power(*other)
    else raise_comparison(other)
    end
end

#==(other) ⇒ Object Also known as: eql?

Only allow value comparison with values of the same class



124
125
126
127
128
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 124

def ==(other)
  (self <=> other) == 0
rescue EnumSetError
  false
end

#[]=(key, value) ⇒ Object

Replace the setter by instantiating the value



153
154
155
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 153

def []=(key, value)
  super(key, instantiate(value))
end

#inspectObject

Change the inspection to show the enum name



148
149
150
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 148

def inspect
  "[#{map(&:inspect).join(', ')}]"
end

#merge(other) ⇒ Object

Override the merge method to ensure formatted values



158
159
160
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 158

def merge(other)
  super other.map(&method(:instantiate))
end

#replace(*values) ⇒ Object

It only accepts if the other value is valid



132
133
134
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 132

def replace(*values)
  super(transform_values(values))
end

#text(attr = nil, model = nil) ⇒ Object Also known as: to_s

Get a translated version of the value



137
138
139
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 137

def text(attr = nil, model = nil)
  map { |item| item.text(attr, model) }.to_sentence
end

#to_iObject

Get the index of the value



143
144
145
# File 'lib/torque/postgresql/attributes/enum_set.rb', line 143

def to_i
  self.class.power(@hash.keys)
end