Class: Shiftable::ModSignature

Inherits:
Object
  • Object
show all
Defined in:
lib/shiftable/mod_signature.rb

Defined Under Namespace

Modules: CxMethods, PcxMethods, SgMethods

Constant Summary collapse

VALID_ASSOCIATIONS =
{ sg: %i[belongs_to has_one], cx: %i[belongs_to has_many], pcx: %i[belongs_to has_many] }.freeze
VALID_TYPES =
VALID_ASSOCIATIONS.keys.dup.freeze
DEFAULT_BEFORE_SHIFT =
->(*_) { true }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(associations:, type:, options: {}) ⇒ ModSignature

Imagine you are a Spaceship Captain, the Spaceship belongs_to you, and it has only one Captain. But you have to sell it to your nemesis!



12
13
14
15
16
17
18
19
# File 'lib/shiftable/mod_signature.rb', line 12

def initialize(associations:, type:, options: {})
  @associations = associations
  @options = options
  @type = type
  # See: https://maximomussini.com/posts/practical-applications-of-the-singleton-class/
  singleton_class.send(:prepend, Object.const_get("Shiftable::ModSignature::#{type.capitalize}Methods", false))
  validate
end

Instance Attribute Details

#associationsObject (readonly)

Returns the value of attribute associations.



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

def associations
  @associations
end

#baseObject (readonly)

Returns the value of attribute base.



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

def base
  @base
end

#optionsObject (readonly)

Returns the value of attribute options.



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

def options
  @options
end

#typeObject (readonly)

Returns the value of attribute type.



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

def type
  @type
end

Instance Method Details

#add_base(base) ⇒ Object

Note:

Chainable

Returns self.

Returns:

  • self



53
54
55
56
# File 'lib/shiftable/mod_signature.rb', line 53

def add_base(base)
  @base = base
  self
end

#before_shiftObject

will prevent the save if it returns false allows for any custom logic to be run, such as setting shift_from attributes, prior to the shift is saved.



161
162
163
# File 'lib/shiftable/mod_signature.rb', line 161

def before_shift
  options[:before_shift] || DEFAULT_BEFORE_SHIFT
end

#belongs_toObject

The name of the belongs_to association, defined on the shifting model, e.g. Spaceship Normally a camel-cased, symbolized, version of the class name. In the case where Spaceship belongs_to: :captain, this is :captain.



151
152
153
# File 'lib/shiftable/mod_signature.rb', line 151

def belongs_to
  associations[:belongs_to]
end

#has_rel_nameObject



58
59
60
# File 'lib/shiftable/mod_signature.rb', line 58

def has_rel_name
  VALID_ASSOCIATIONS[type][1]
end

#invalid_association_key_type?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/shiftable/mod_signature.rb', line 43

def invalid_association_key_type?
  associations.keys.detect { |key| !key.is_a?(Symbol) }
end

#invalid_number_of_associations?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/shiftable/mod_signature.rb', line 47

def invalid_number_of_associations?
  associations.keys.uniq.length != 2
end

#invalid_type?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/shiftable/mod_signature.rb', line 39

def invalid_type?
  !VALID_TYPES.include?(type)
end

#method_prefixObject



155
156
157
# File 'lib/shiftable/mod_signature.rb', line 155

def method_prefix
  options[:method_prefix]
end

#polymorphic_asObject



35
36
37
# File 'lib/shiftable/mod_signature.rb', line 35

def polymorphic_as
  options.dig(:polymorphic, :as)
end

#polymorphic_typeObject



31
32
33
# File 'lib/shiftable/mod_signature.rb', line 31

def polymorphic_type
  options.dig(:polymorphic, :type)
end

#shift_columnObject Also known as: shift_sg_column, shift_cx_column



169
170
171
172
# File 'lib/shiftable/mod_signature.rb', line 169

def shift_column
  reflection = base.reflect_on_association(belongs_to).klass.reflect_on_association(has_rel)
  reflection.foreign_key
end

#shift_pcx_columnObject



165
166
167
# File 'lib/shiftable/mod_signature.rb', line 165

def shift_pcx_column
  "#{polymorphic_as}_id"
end

#validateObject

Raises:

  • (ArgumentError)


21
22
23
24
25
# File 'lib/shiftable/mod_signature.rb', line 21

def validate
  raise ArgumentError, "type must be one of: #{VALID_TYPES}, provided: #{type}" if invalid_type?
  raise ArgumentError, "associations must be symbols" if invalid_association_key_type?
  raise ArgumentError, "exactly two distinct associations must be provided" if invalid_number_of_associations?
end

#validate_relationshipsObject

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
69
70
71
# File 'lib/shiftable/mod_signature.rb', line 62

def validate_relationships
  bt_reflection = base.reflect_on_association(belongs_to)
  raise ArgumentError, "Unable to find belongs_to: :#{belongs_to} in #{base}" unless bt_reflection
  # We can't validate any further if the reflection is polymorphic
  return true if bt_reflection.polymorphic?

  klass = bt_reflection.klass
  has_reflection = klass.reflect_on_association(has_rel)
  raise ArgumentError, "Unable to find #{has_rel_name}: :#{has_rel} in #{klass}" unless has_reflection
end

#wrapperObject



27
28
29
# File 'lib/shiftable/mod_signature.rb', line 27

def wrapper
  options[:wrapper] || {}
end