Class: Amount::ActiveRecord::AttributeDefinition
- Inherits:
-
Object
- Object
- Amount::ActiveRecord::AttributeDefinition
- Defined in:
- lib/amount/active_record/attribute_definition.rb
Overview
Describes one ‘has_amount` attribute and its backing columns.
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#symbol ⇒ Object
readonly
Returns the value of attribute symbol.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Instance Method Summary collapse
- #atomic_column ⇒ Object
- #before_last_save(record) ⇒ Object
- #between_relation(model, lower, upper) ⇒ Object
- #build_from_values(values) ⇒ Object
- #change(record) ⇒ Object
- #changed?(record) ⇒ Boolean
- #component_columns ⇒ Object
- #currency_relation(model, symbol) ⇒ Object
- #fixed_symbol? ⇒ Boolean
- #greater_than_or_equal_relation(model, value) ⇒ Object
- #greater_than_relation(model, value) ⇒ Object
-
#initialize(name, symbol: nil) ⇒ AttributeDefinition
constructor
A new instance of AttributeDefinition.
- #less_than_or_equal_relation(model, value) ⇒ Object
- #less_than_relation(model, value) ⇒ Object
- #query_relation(model, value) ⇒ Object
- #read(record) ⇒ Object
- #saved_change(record) ⇒ Object
- #saved_change?(record) ⇒ Boolean
- #symbol_column ⇒ Object
- #validate(record) ⇒ Object
- #value_in_database(record) ⇒ Object
- #write(record, value) ⇒ Object
Constructor Details
#initialize(name, symbol: nil) ⇒ AttributeDefinition
Returns a new instance of AttributeDefinition.
9 10 11 12 13 |
# File 'lib/amount/active_record/attribute_definition.rb', line 9 def initialize(name, symbol: nil) @name = name.to_sym @symbol = symbol&.to_sym @type = Type.new(symbol: @symbol) end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
7 8 9 |
# File 'lib/amount/active_record/attribute_definition.rb', line 7 def name @name end |
#symbol ⇒ Object (readonly)
Returns the value of attribute symbol.
7 8 9 |
# File 'lib/amount/active_record/attribute_definition.rb', line 7 def symbol @symbol end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
7 8 9 |
# File 'lib/amount/active_record/attribute_definition.rb', line 7 def type @type end |
Instance Method Details
#atomic_column ⇒ Object
19 20 21 |
# File 'lib/amount/active_record/attribute_definition.rb', line 19 def atomic_column "#{name}_atomic" end |
#before_last_save(record) ⇒ Object
118 119 120 |
# File 'lib/amount/active_record/attribute_definition.rb', line 118 def before_last_save(record) saved_change(record)&.first end |
#between_relation(model, lower, upper) ⇒ Object
74 75 76 77 78 79 80 81 |
# File 'lib/amount/active_record/attribute_definition.rb', line 74 def between_relation(model, lower, upper) lower_amount = type.cast(lower) upper_amount = type.cast(upper) ensure_same_query_symbol!(lower_amount, upper_amount) relation_for_symbol(model, lower_amount) .where("#{atomic_column} >= ? AND #{atomic_column} <= ?", lower_amount.atomic, upper_amount.atomic) end |
#build_from_values(values) ⇒ Object
49 50 51 |
# File 'lib/amount/active_record/attribute_definition.rb', line 49 def build_from_values(values) type.deserialize(values[atomic_column], fixed_symbol? ? symbol : values[symbol_column]) end |
#change(record) ⇒ Object
91 92 93 94 95 |
# File 'lib/amount/active_record/attribute_definition.rb', line 91 def change(record) return unless changed?(record) [value_in_database(record), read(record)] end |
#changed?(record) ⇒ Boolean
87 88 89 |
# File 'lib/amount/active_record/attribute_definition.rb', line 87 def changed?(record) component_columns.any? { |column| record.will_save_change_to_attribute?(column) } end |
#component_columns ⇒ Object
27 28 29 30 31 |
# File 'lib/amount/active_record/attribute_definition.rb', line 27 def component_columns columns = [atomic_column] columns << symbol_column unless fixed_symbol? columns end |
#currency_relation(model, symbol) ⇒ Object
83 84 85 |
# File 'lib/amount/active_record/attribute_definition.rb', line 83 def currency_relation(model, symbol) model.where(symbol_column => symbol.to_s) end |
#fixed_symbol? ⇒ Boolean
15 16 17 |
# File 'lib/amount/active_record/attribute_definition.rb', line 15 def fixed_symbol? !@symbol.nil? end |
#greater_than_or_equal_relation(model, value) ⇒ Object
62 63 64 |
# File 'lib/amount/active_record/attribute_definition.rb', line 62 def greater_than_or_equal_relation(model, value) query_relation_with_operator(model, value, :>=) end |
#greater_than_relation(model, value) ⇒ Object
58 59 60 |
# File 'lib/amount/active_record/attribute_definition.rb', line 58 def greater_than_relation(model, value) query_relation_with_operator(model, value, :>) end |
#less_than_or_equal_relation(model, value) ⇒ Object
70 71 72 |
# File 'lib/amount/active_record/attribute_definition.rb', line 70 def less_than_or_equal_relation(model, value) query_relation_with_operator(model, value, :<=) end |
#less_than_relation(model, value) ⇒ Object
66 67 68 |
# File 'lib/amount/active_record/attribute_definition.rb', line 66 def less_than_relation(model, value) query_relation_with_operator(model, value, :<) end |
#query_relation(model, value) ⇒ Object
53 54 55 56 |
# File 'lib/amount/active_record/attribute_definition.rb', line 53 def query_relation(model, value) amount = type.cast(value) relation_for_symbol(model, amount).where(atomic_column => amount.atomic) end |
#read(record) ⇒ Object
33 34 35 |
# File 'lib/amount/active_record/attribute_definition.rb', line 33 def read(record) type.deserialize(record.read_attribute(atomic_column), resolved_symbol(record)) end |
#saved_change(record) ⇒ Object
109 110 111 112 113 114 115 116 |
# File 'lib/amount/active_record/attribute_definition.rb', line 109 def saved_change(record) return unless saved_change?(record) [ build_from_values(previous_values(record, before: true)), build_from_values(previous_values(record, before: false)) ] end |
#saved_change?(record) ⇒ Boolean
105 106 107 |
# File 'lib/amount/active_record/attribute_definition.rb', line 105 def saved_change?(record) component_columns.any? { |column| record.saved_change_to_attribute?(column) } end |
#symbol_column ⇒ Object
23 24 25 |
# File 'lib/amount/active_record/attribute_definition.rb', line 23 def symbol_column "#{name}_symbol" end |
#validate(record) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/amount/active_record/attribute_definition.rb', line 122 def validate(record) add_assignment_error(record) atomic = record.read_attribute(atomic_column) return if atomic.nil? && fixed_symbol? if fixed_symbol? validate_deserialization(record, atomic, symbol) return end symbol_value = record.read_attribute(symbol_column) if atomic.nil? != symbol_value.nil? record.errors.add(name, "must set both atomic and symbol or neither") return end return if atomic.nil? && symbol_value.nil? validate_deserialization(record, atomic, symbol_value) end |
#value_in_database(record) ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/amount/active_record/attribute_definition.rb', line 97 def value_in_database(record) values = component_columns.to_h do |column| [column, record.attribute_in_database(column)] end build_from_values(values) end |
#write(record, value) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/amount/active_record/attribute_definition.rb', line 37 def write(record, value) if value.nil? record.write_attribute(atomic_column, nil) record.write_attribute(symbol_column, nil) unless fixed_symbol? return nil end record.write_attribute(atomic_column, value.atomic.to_s) record.write_attribute(symbol_column, value.symbol.to_s) unless fixed_symbol? value end |