Module: HashAttributes
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/hash_attributes/version.rb,
lib/hash_attributes/hash_attributes.rb,
lib/hash_attributes/date_time_serializer.rb
Defined Under Namespace
Modules: ClassMethods
Classes: DateTimeSerializer
Constant Summary
collapse
- VERSION =
"1.0.0"
Instance Method Summary
collapse
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_symbol, *args, &block) ⇒ Object
207
208
209
210
211
212
213
214
215
216
217
218
|
# File 'lib/hash_attributes/hash_attributes.rb', line 207
def method_missing(method_symbol, *args, &block)
attribute_name = self.class.(method_symbol)
if attribute_name.present? &&
self.class.column_names.include?(attribute_name) == false &&
self.class.method_defined?(attribute_name) == false
self.class.define_hash_column_attribute(attribute_name)
__send__(method_symbol, *args)
else
super
end
end
|
Instance Method Details
#[](attribute_name) ⇒ Object
112
113
114
|
# File 'lib/hash_attributes/hash_attributes.rb', line 112
def [](attribute_name)
read_attribute(attribute_name)
end
|
#[]=(attribute_name, value) ⇒ Object
116
117
118
|
# File 'lib/hash_attributes/hash_attributes.rb', line 116
def []=(attribute_name, value)
write_attribute(attribute_name, value)
end
|
#assign_attributes(new_attributes) ⇒ Object
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/hash_attributes/hash_attributes.rb', line 152
def assign_attributes(new_attributes)
return if new_attributes.blank?
new_attributes = new_attributes.with_indifferent_access
__hash_column_attributes__ = new_attributes.except(*self.class.column_names)
if __hash_column_attributes__.present?
__hash_column_attributes__ = {self.class.hash_column => read_attribute(self.class.hash_column).merge(__hash_column_attributes__)}
new_attributes = new_attributes.slice(*self.class.column_names).merge(__hash_column_attributes__)
end
super(new_attributes)
end
|
#attribute_names ⇒ Object
128
129
130
|
# File 'lib/hash_attributes/hash_attributes.rb', line 128
def attribute_names
((self.class.column_names - [self.class.hash_column]) + hash_column_attribute_names).sort
end
|
#attributes ⇒ Object
132
133
134
|
# File 'lib/hash_attributes/hash_attributes.rb', line 132
def attributes
(super || {}).with_indifferent_access.except(self.class.hash_column).merge(hash_column_attributes)
end
|
#attributes_before_type_cast ⇒ Object
94
95
96
97
98
99
100
101
102
|
# File 'lib/hash_attributes/hash_attributes.rb', line 94
def attributes_before_type_cast
self.class.column_names.inject(HashWithIndifferentAccess.new) do |result, attribute_name|
if attribute_name == self.class.hash_column
result.merge(read_attribute(attribute_name) || {})
else
result.merge(attribute_name => read_attribute(attribute_name))
end
end
end
|
#cache_key ⇒ Object
169
170
171
|
# File 'lib/hash_attributes/hash_attributes.rb', line 169
def cache_key
"#{self.class.name.underscore.dasherize}-#{read_attribute(self.class.primary_key)}-version-#{Digest::MD5.hexdigest(attributes.inspect)}"
end
|
#column_for_attribute(attribute_name) ⇒ Object
136
137
138
139
140
141
142
143
|
# File 'lib/hash_attributes/hash_attributes.rb', line 136
def column_for_attribute(attribute_name)
attribute_name = attribute_name.to_s
if is_valid_hash_column_attribute_name?(attribute_name)
nil
else
super(attribute_name)
end
end
|
#delete_hash_column_attribute(attribute_name) ⇒ Object
177
178
179
180
181
182
183
184
185
186
187
|
# File 'lib/hash_attributes/hash_attributes.rb', line 177
def delete_hash_column_attribute(attribute_name)
if is_valid_hash_column_attribute_name?(attribute_name)
__hash_column_value__ = read_attribute(self.class.hash_column)
__result__ = __hash_column_value__.delete(attribute_name)
write_attribute(self.class.hash_column, __hash_column_value__)
self.class.undefine_attribute_method(attribute_name)
__result__
else
nil
end
end
|
#has_attribute?(attribute_name) ⇒ Boolean
145
146
147
148
|
# File 'lib/hash_attributes/hash_attributes.rb', line 145
def has_attribute?(attribute_name)
attribute_name = attribute_name.to_s
hash_column_attribute_names.include?(attribute_name) || super(attribute_name)
end
|
#hash_column_attribute_names ⇒ Object
124
125
126
|
# File 'lib/hash_attributes/hash_attributes.rb', line 124
def hash_column_attribute_names
read_attribute(self.class.hash_column).keys.sort
end
|
#hash_column_attributes ⇒ Object
120
121
122
|
# File 'lib/hash_attributes/hash_attributes.rb', line 120
def hash_column_attributes
self.class.deserialize_hash_column_attribute(self.class.hash_column, read_attribute(self.class.hash_column))
end
|
#initialize(*args, &block) ⇒ Object
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# File 'lib/hash_attributes/hash_attributes.rb', line 8
def initialize(*args, &block)
if args[0].is_a?(Hash)
args[0] = args[0].with_indifferent_access
args[0] = args[0].inject(HashWithIndifferentAccess.new(self.class.hash_column => {})) do |result, (attribute_name, value)|
if self.class.hash_column == attribute_name
result[self.class.hash_column].merge!(value)
elsif self.class.column_names.include?(attribute_name)
result[attribute_name] = value
else
result[self.class.hash_column][attribute_name] = value
end
result
end
end
if block_given?
super(*args) do |new_record|
yield new_record if block_given?
end
else
super(*args)
end
end
|
#inspect ⇒ Object
173
174
175
|
# File 'lib/hash_attributes/hash_attributes.rb', line 173
def inspect
"#<#{self.class.name} #{attributes.map{ |k, v| "#{k}: #{v.inspect}" }.join(", ")}>"
end
|
#is_valid_hash_column_attribute_name?(attribute_name) ⇒ Boolean
32
33
34
35
|
# File 'lib/hash_attributes/hash_attributes.rb', line 32
def is_valid_hash_column_attribute_name?(attribute_name)
attribute_name = attribute_name.to_s
self.class.column_names.include?(attribute_name) == false && self.class.is_valid_attribute_name?(attribute_name)
end
|
#query_attribute(attribute_name) ⇒ Object
107
108
109
|
# File 'lib/hash_attributes/hash_attributes.rb', line 107
def query_attribute(attribute_name)
is_valid_hash_column_attribute_name?(attribute_name) || super(attribute_name)
end
|
#read_attribute(attribute_name) ⇒ Object
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/hash_attributes/hash_attributes.rb', line 40
def read_attribute(attribute_name)
attribute_name = attribute_name.to_s
if attribute_name == self.class.hash_column
(super(attribute_name) || {}).with_indifferent_access
elsif is_valid_hash_column_attribute_name?(attribute_name)
read_hash_column_attribute(attribute_name)
else
super(attribute_name)
end
end
|
#read_attribute_before_type_cast(attribute_name) ⇒ Object
86
87
88
89
90
91
92
|
# File 'lib/hash_attributes/hash_attributes.rb', line 86
def read_attribute_before_type_cast(attribute_name)
if is_valid_hash_column_attribute_name?(attribute_name)
read_hash_column_attribute(attribute_name)
else
super(attribute_name)
end
end
|
#read_hash_column_attribute(attribute_name) ⇒ Object
51
52
53
|
# File 'lib/hash_attributes/hash_attributes.rb', line 51
def read_hash_column_attribute(attribute_name)
self.class.deserialize_hash_column_attribute(attribute_name, read_attribute(self.class.hash_column).try(:[], attribute_name))
end
|
#respond_to?(method_symbol, include_private = false) ⇒ Boolean
198
199
200
201
202
203
204
205
|
# File 'lib/hash_attributes/hash_attributes.rb', line 198
def respond_to?(method_symbol, include_private = false)
if super
true
else
attribute_name = self.class.(method_symbol)
attribute_name.present? && hash_column_attribute_names.include?(attribute_name)
end
end
|
#to_h ⇒ Object
163
164
165
|
# File 'lib/hash_attributes/hash_attributes.rb', line 163
def to_h
serializable_hash.with_indifferent_access
end
|
#update_columns(attributes) ⇒ Object
189
190
191
192
193
194
195
196
|
# File 'lib/hash_attributes/hash_attributes.rb', line 189
def update_columns(attributes)
__hash_column_attributes__ = attributes.except(*self.class.column_names)
if __hash_column_attributes__.present?
__hash_column_attributes__ = self.class.serialize_hash_column_attribute(self.class.hash_column, __hash_column_attributes__)
attributes = attributes.slice(*self.class.column_names).merge({self.class.hash_column => __hash_column_attributes__})
end
super(attributes)
end
|
#write_attribute(attribute_name, value) ⇒ Object
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/hash_attributes/hash_attributes.rb', line 58
def write_attribute(attribute_name, value)
attribute_name = attribute_name.to_s
if attribute_name == self.class.hash_column
value = value.try(:with_indifferent_access)
unless read_attribute(self.class.hash_column).try(:with_indifferent_access) == value
attribute_will_change!(attribute_name)
end
super(self.class.hash_column, self.class.serialize_hash_column_attribute(self.class.hash_column, value))
value
elsif is_valid_hash_column_attribute_name?(attribute_name)
write_hash_column_attribute(attribute_name, value)
else
super(attribute_name, value)
end
end
|
#write_hash_column_attribute(attribute_name, value) ⇒ Object
74
75
76
77
78
79
80
81
|
# File 'lib/hash_attributes/hash_attributes.rb', line 74
def write_hash_column_attribute(attribute_name, value)
if value != read_attribute(attribute_name)
verify_readonly_attribute(attribute_name)
attribute_will_change!(attribute_name)
write_attribute(self.class.hash_column, read_attribute(self.class.hash_column).merge(attribute_name => value))
end
value
end
|