activerecord-typedstore 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 542197f677322bd49dc623661de6f72adae6e259
|
4
|
+
data.tar.gz: 8612b393a7cbc50203a8848c9928dfade4776ef2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a06189e792adec4ac11a2bc6020439135051a1d7194f21d43008d9077fcef511ddcf9f8d252f5f25478aa9220425b38bc03655462a6138b04e9e941bcfdcc566
|
7
|
+
data.tar.gz: dfc9469b4dd7c9e1dbb611db6db1e150ac643d6f52f890f58665308f384457cf5a0b2f6a7e885af51ff7db48f16d996971a3b12229bf8e226bd53a9c188c0bcb
|
data/README.md
CHANGED
@@ -66,6 +66,12 @@ shop.update_attributes(
|
|
66
66
|
shop.age # => 42
|
67
67
|
shop.published_at.class #= DateTime
|
68
68
|
|
69
|
+
# And changes are tracked
|
70
|
+
shop.age_changed? # => false
|
71
|
+
shop.age = 12
|
72
|
+
shop.age_changed? # => true
|
73
|
+
shop.age_was # => 42
|
74
|
+
|
69
75
|
# You can still use it as a regular store
|
70
76
|
shop.settings[:unknown] = 'Hello World'
|
71
77
|
shop.save
|
@@ -3,6 +3,11 @@ module ActiveRecord::TypedStore
|
|
3
3
|
module AR32Fallbacks
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
included do
|
7
|
+
cattr_accessor :virtual_attribute_methods
|
8
|
+
self.virtual_attribute_methods = []
|
9
|
+
end
|
10
|
+
|
6
11
|
module ClassMethods
|
7
12
|
|
8
13
|
def typed_store(store_attribute, options={}, &block)
|
@@ -12,6 +17,24 @@ module ActiveRecord::TypedStore
|
|
12
17
|
|
13
18
|
protected
|
14
19
|
|
20
|
+
def define_virtual_attribute_method(name)
|
21
|
+
virtual_attribute_methods << name
|
22
|
+
define_attribute_method(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
# ActiveModel override heavilly inspired from the original code
|
26
|
+
def define_attribute_method(attr_name)
|
27
|
+
return super unless virtual_attribute_methods.include?(attr_name)
|
28
|
+
|
29
|
+
attribute_method_matchers.each do |matcher|
|
30
|
+
method_name = matcher.method_name(attr_name)
|
31
|
+
unless instance_method_already_implemented?(method_name)
|
32
|
+
define_optimized_call generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
attribute_method_matchers_cache.clear
|
36
|
+
end
|
37
|
+
|
15
38
|
def _ar_32_fallback_accessors(store_attribute, columns)
|
16
39
|
_ar_32_fallback_initializer(store_attribute, columns)
|
17
40
|
columns.each do |column|
|
@@ -39,7 +62,9 @@ module ActiveRecord::TypedStore
|
|
39
62
|
|
40
63
|
def _ar_32_fallback_writer(store_attribute, column)
|
41
64
|
define_method("#{column.name}_with_type_casting=") do |value|
|
42
|
-
|
65
|
+
casted_value = column.cast(value)
|
66
|
+
attribute_will_change!(column.name.to_s) if casted_value != send(column.name)
|
67
|
+
send("#{column.name}_without_type_casting=", casted_value)
|
43
68
|
end
|
44
69
|
alias_method_chain "#{column.name}=", :type_casting
|
45
70
|
end
|
@@ -7,6 +7,10 @@ module ActiveRecord::TypedStore
|
|
7
7
|
IS_AR_4_0 = AR_VERSION >= Gem::Version.new('4.0') && AR_VERSION < Gem::Version.new('4.1.0.beta')
|
8
8
|
IS_AR_4_1 = AR_VERSION >= Gem::Version.new('4.1.0.beta')
|
9
9
|
|
10
|
+
unless IS_AR_3_2
|
11
|
+
ActiveModel::AttributeMethods::ClassMethods.send(:alias_method, :define_virtual_attribute_method, :define_attribute_method)
|
12
|
+
end
|
13
|
+
|
10
14
|
module Extension
|
11
15
|
extend ActiveSupport::Concern
|
12
16
|
|
@@ -27,6 +31,8 @@ module ActiveRecord::TypedStore
|
|
27
31
|
stored_typed_attributes[store_attribute] ||= {}
|
28
32
|
stored_typed_attributes[store_attribute].merge!(dsl.columns.index_by(&:name))
|
29
33
|
|
34
|
+
dsl.column_names.each { |c| define_virtual_attribute_method(c.to_s) }
|
35
|
+
|
30
36
|
dsl
|
31
37
|
end
|
32
38
|
|
@@ -42,6 +48,7 @@ module ActiveRecord::TypedStore
|
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
51
|
+
attribute_will_change!(key.to_s) if casted_value != read_store_attribute(store_attribute, key)
|
45
52
|
super(store_attribute, key, casted_value)
|
46
53
|
end
|
47
54
|
|
@@ -26,6 +26,41 @@ shared_examples 'any model' do
|
|
26
26
|
|
27
27
|
end
|
28
28
|
|
29
|
+
describe 'dirty tracking' do
|
30
|
+
|
31
|
+
it 'track changed attributes' do
|
32
|
+
expect {
|
33
|
+
model.age = 24
|
34
|
+
}.to change { model.age_changed? }.from(false).to(true)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'keep track of what the attribute was' do
|
38
|
+
model.age = 24
|
39
|
+
expect(model.age_was).to be == 12
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'keep track of the whole changes' do
|
43
|
+
expect {
|
44
|
+
model.age = 24
|
45
|
+
}.to change { model.changes['age'] }.from(nil).to([12, 24])
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'reset recorded changes after successful save' do
|
49
|
+
model.age = 24
|
50
|
+
expect {
|
51
|
+
model.save
|
52
|
+
}.to change { model.age_changed? }.from(true).to(false)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can be reset individually' do
|
56
|
+
model.age = 24
|
57
|
+
expect {
|
58
|
+
model.reset_age!
|
59
|
+
}.to change { model.age }.from(24).to(12)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
29
64
|
describe 'unknown attribute' do
|
30
65
|
|
31
66
|
it 'raise an ActiveRecord::UnknownAttributeError on save attemps' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-typedstore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|