property_sets 3.5.3 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5b1904f990b0edf7d1a91f1ac6b703f9bddc428d280e031ae4daaa6983f6835
4
- data.tar.gz: cea92b99f11a508d543d9ff4f812e9326ae30aefa06e448619b19ab6dc1dbe02
3
+ metadata.gz: d4202c89da527945bdf58692cdd2c99c98090b130b674605ad4d97d6938b48f7
4
+ data.tar.gz: c1ce9e1690953791c8325405ce6fe398b251acc2095868e238146d5e560fc173
5
5
  SHA512:
6
- metadata.gz: bc1e1b4afd64f05275f2123fb05e9614009eb3ecfb4e8d4940fc74811300a15c2cd7dc13db75ec9d5883d66f81aa2ec4ae637e7039f10ffedbadcb198190c499
7
- data.tar.gz: 976d4c41225d97445c1c9ebf78b19d55d97465c1dce1731fb648d81b1d4e9a35b3446cbfb2e3a5491a6e63c3a1b7172c92533303cc239853c409cb558f951323
6
+ metadata.gz: 6f62d70197d3fcb43434d5504187deb5667275f9a0a34d7884f2b57e23ab0e84122ed4f56c68f48a55ac74cd97ef9a7d59a042e9e1fa3e005592f09abe5c9bee
7
+ data.tar.gz: 3225b1bf41f59c63b43dd5ebce79f048b6933fc47345d2089a03bbcbf613b5e1c0877dbc508647a187f2ca999d88375263ec5e3bd9a660b469daf0fad669a027
data/lib/property_sets.rb CHANGED
@@ -10,16 +10,19 @@ end
10
10
  module PropertySets
11
11
  def self.ensure_property_set_class(association, owner_class_name)
12
12
  const_name = "#{owner_class_name}#{association.to_s.singularize.camelcase}".to_sym
13
+
13
14
  unless Object.const_defined?(const_name)
14
- property_class = Object.const_set(const_name, Class.new(ActiveRecord::Base))
15
- property_class.class_eval do
15
+ property_class = Class.new(ActiveRecord::Base) do
16
16
  include PropertySets::PropertySetModel::InstanceMethods
17
17
  extend PropertySets::PropertySetModel::ClassMethods
18
18
  end
19
19
 
20
+ Object.const_set(const_name, property_class)
21
+
20
22
  property_class.owner_class = owner_class_name
21
23
  property_class.owner_assoc = association
22
24
  end
25
+
23
26
  Object.const_get(const_name)
24
27
  end
25
28
  end
@@ -6,6 +6,8 @@ module PropertySets
6
6
  module ActiveRecordExtension
7
7
  module ClassMethods
8
8
 
9
+ RAILS6 = ActiveRecord::VERSION::MAJOR >= 6
10
+
9
11
  def property_set(association, options = {}, &block)
10
12
  unless include?(PropertySets::ActiveRecordExtension::InstanceMethods)
11
13
  self.send(:prepend, PropertySets::ActiveRecordExtension::InstanceMethods)
@@ -14,52 +16,84 @@ module PropertySets
14
16
  end
15
17
 
16
18
  raise "Invalid association name, letters only" unless association.to_s =~ /[a-z]+/
19
+ exists = property_set_index.include?(association)
20
+
17
21
  self.property_set_index << association
18
22
 
23
+ # eg AccountSetting - this IS idempotent
19
24
  property_class = PropertySets.ensure_property_set_class(
20
25
  association,
21
26
  options.delete(:owner_class_name) || self.name
22
27
  )
23
- property_class.instance_eval(&block)
24
28
 
25
- hash_opts = {:class_name => property_class.name, :autosave => true, :dependent => :destroy}.merge(options)
29
+ # eg property :is_awesome
30
+ property_class.instance_eval(&block) if block
31
+
32
+ tb_name = options.delete :table_name
33
+ property_class.table_name = tb_name if tb_name
34
+
35
+ hash_opts = {
36
+ :class_name => property_class.name,
37
+ :autosave => true,
38
+ :dependent => :destroy,
39
+ :inverse_of => self.name.underscore.to_sym,
40
+ }.merge(options)
41
+
42
+ # TODO: should check options are compatible? warn? raise?
43
+ reflection = self.reflections[association.to_s] # => ActiveRecord::Reflection::HasManyReflection
44
+ reflection.options.merge! options if reflection && !options.empty?
26
45
 
27
- silence_warnings do
46
+ unless exists then # makes has_many idempotent...
28
47
  has_many association, hash_opts do
29
- include PropertySets::ActiveRecordExtension::AssociationExtensions
30
-
31
- property_class.keys.each do |key|
32
- raise "Invalid property key #{key}" if self.respond_to?(key)
33
-
34
- # Reports the coerced truth value of the property
35
- define_method "#{key}?" do
36
- type = property_class.type(key)
37
- value = lookup_value(type, key)
38
- ![ "false", "0", "", "off", "n" ].member?(value.to_s.downcase)
39
- end
40
-
41
- # Returns the value of the property
42
- define_method "#{key}" do
43
- type = property_class.type(key)
44
- lookup_value(type, key)
45
- end
46
-
47
- # Assigns a new value to the property
48
- define_method "#{key}=" do |value|
49
- instance = lookup(key)
50
- instance.value = PropertySets::Casting.write(property_class.type(key), value)
51
- instance.value
52
- end
53
-
54
- define_method "#{key}_record" do
55
- lookup(key)
56
- end
48
+ # keep this damn block! -- creates association_module below
49
+ end
50
+ end
51
+
52
+ # eg 5: AccountSettingsAssociationExtension
53
+ # eg 6: Account::SettingsAssociationExtension
54
+
55
+ # stolen/adapted from AR's collection_association.rb #define_extensions
56
+
57
+ module_name = "#{association.to_s.camelize}AssociationExtension"
58
+ module_name = name.demodulize + module_name unless RAILS6
59
+
60
+ target = RAILS6 ? self : self.parent
61
+ association_module = target.const_get module_name
62
+
63
+ association_module.module_eval do
64
+ include PropertySets::ActiveRecordExtension::AssociationExtensions
65
+
66
+ property_class.keys.each do |key|
67
+ raise "Invalid property key #{key}" if self.respond_to?(key)
68
+
69
+ # Reports the coerced truth value of the property
70
+ define_method "#{key}?" do
71
+ type = property_class.type(key)
72
+ value = lookup_value(type, key)
73
+ ![ "false", "0", "", "off", "n" ].member?(value.to_s.downcase)
74
+ end
75
+
76
+ # Returns the value of the property
77
+ define_method "#{key}" do
78
+ type = property_class.type(key)
79
+ lookup_value(type, key)
80
+ end
81
+
82
+ # Assigns a new value to the property
83
+ define_method "#{key}=" do |value|
84
+ instance = lookup(key)
85
+ instance.value = PropertySets::Casting.write(property_class.type(key), value)
86
+ instance.value
57
87
  end
58
88
 
59
- define_method :property_serialized? do |key|
60
- property_class.type(key) == :serialized
89
+ define_method "#{key}_record" do
90
+ lookup(key)
61
91
  end
62
92
  end
93
+
94
+ define_method :property_serialized? do |key|
95
+ property_class.type(key) == :serialized
96
+ end
63
97
  end
64
98
  end
65
99
  end
@@ -184,6 +218,35 @@ module PropertySets
184
218
  end
185
219
  end
186
220
  end
221
+
222
+ def update_columns(attributes)
223
+ if delegated_property_sets?
224
+ attributes = attributes.reject{|k,_| self.class.delegated_property_set_attributes.include?(k.to_s) }
225
+ end
226
+
227
+ super attributes
228
+ end
229
+
230
+ private
231
+
232
+ def delegated_property_sets?
233
+ self.class.respond_to?(:delegated_property_set_attributes)
234
+ end
235
+
236
+ def attributes_for_create(attribute_names)
237
+ super filter_delegated_property_set_attributes(attribute_names)
238
+ end
239
+
240
+ def attributes_for_update(attribute_names)
241
+ super filter_delegated_property_set_attributes(attribute_names)
242
+ end
243
+
244
+ def filter_delegated_property_set_attributes(attribute_names)
245
+ if delegated_property_sets?
246
+ return attribute_names - self.class.delegated_property_set_attributes.to_a
247
+ end
248
+ attribute_names
249
+ end
187
250
  end
188
251
 
189
252
  end
@@ -20,18 +20,35 @@ module PropertySets
20
20
  def delegate_to_property_set(setname, mappings)
21
21
  raise "Second argument must be a Hash" unless mappings.is_a?(Hash)
22
22
 
23
+ unless respond_to?(:delegated_property_set_attributes)
24
+ class_attribute :delegated_property_set_attributes
25
+ end
26
+ self.delegated_property_set_attributes ||= []
27
+
23
28
  mappings.each do |old_attr, new_attr|
29
+ self.delegated_property_set_attributes << old_attr.to_s
24
30
  if ActiveRecord.version < Gem::Version.new("5.0")
25
31
  attribute old_attr, ActiveRecord::Type::Value.new
26
32
  else
27
33
  attribute old_attr, ActiveModel::Type::Value.new
28
34
  end
29
- define_method(old_attr) { send(setname).send(new_attr) }
35
+ define_method(old_attr) {
36
+ association = send(setname)
37
+ type = association.association_class.type(new_attr)
38
+ association.lookup_value(type, new_attr)
39
+ }
30
40
  alias_method "#{old_attr}_before_type_cast", old_attr
31
41
  define_method("#{old_attr}?") { send(setname).send("#{new_attr}?") }
32
42
  define_method("#{old_attr}=") do |value|
43
+ if send(old_attr) != value
44
+ send("#{old_attr}_will_change!")
45
+ end
33
46
  send(setname).send("#{new_attr}=", value)
34
- super(value)
47
+ super(value) if defined?(super) # Rails 4 does not define this
48
+ end
49
+
50
+ define_method("#{old_attr}_will_change!") do
51
+ attribute_will_change!(old_attr)
35
52
  end
36
53
 
37
54
  define_method("#{old_attr}_changed?") do
@@ -48,6 +65,12 @@ module PropertySets
48
65
  end
49
66
  end
50
67
  end
68
+
69
+ # These are not database columns and should not be included in queries but
70
+ # using the attributes API is the only way to track changes in the main model
71
+ if respond_to?(:user_provided_columns)
72
+ self.user_provided_columns.reject!{|k,_| delegated_property_set_attributes.include?(k.to_s) }
73
+ end
51
74
  end
52
75
  end
53
76
  end
@@ -108,13 +108,16 @@ module PropertySets
108
108
  base.attr_accessible :name, :value if defined?(ProtectedAttributes)
109
109
  end
110
110
 
111
- def property(key, options = nil)
111
+ def properties
112
112
  @properties ||= HashWithIndifferentAccess.new
113
- @properties[key] = options
113
+ end
114
+
115
+ def property(key, options = nil)
116
+ properties[key] = options
114
117
  end
115
118
 
116
119
  def keys
117
- @properties.keys
120
+ properties.keys
118
121
  end
119
122
 
120
123
  def default(key)
@@ -122,15 +125,15 @@ module PropertySets
122
125
  end
123
126
 
124
127
  def raw_default(key)
125
- @properties[key].try(:[], :default)
128
+ properties[key].try(:[], :default)
126
129
  end
127
130
 
128
131
  def type(key)
129
- @properties[key].try(:[], :type) || :string
132
+ properties[key].try(:[], :type) || :string
130
133
  end
131
134
 
132
135
  def protected?(key)
133
- @properties[key].try(:[], :protected) || false
136
+ properties[key].try(:[], :protected) || false
134
137
  end
135
138
 
136
139
  def owner_class=(owner_class_name)
@@ -1,3 +1,3 @@
1
1
  module PropertySets
2
- VERSION = "3.5.3"
2
+ VERSION = "3.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: property_sets
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.3
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Morten Primdahl
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-02 00:00:00.000000000 Z
11
+ date: 2021-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '4.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.1'
22
+ version: '6.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '4.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.1'
32
+ version: '6.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: json
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -100,20 +100,6 @@ dependencies:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
- - !ruby/object:Gem::Dependency
104
- name: wwtd
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: 0.5.3
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: 0.5.3
117
103
  - !ruby/object:Gem::Dependency
118
104
  name: byebug
119
105
  requirement: !ruby/object:Gem::Requirement
@@ -146,7 +132,7 @@ homepage: http://github.com/zendesk/property_sets
146
132
  licenses:
147
133
  - MIT
148
134
  metadata: {}
149
- post_install_message:
135
+ post_install_message:
150
136
  rdoc_options: []
151
137
  require_paths:
152
138
  - lib
@@ -162,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
148
  version: '0'
163
149
  requirements: []
164
150
  rubygems_version: 3.0.3
165
- signing_key:
151
+ signing_key:
166
152
  specification_version: 4
167
153
  summary: Property sets for ActiveRecord.
168
154
  test_files: []