property_sets 3.10.0 → 3.11.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 +4 -4
- data/lib/property_sets/action_view_extension.rb +12 -14
- data/lib/property_sets/active_record_extension.rb +29 -29
- data/lib/property_sets/casting.rb +3 -3
- data/lib/property_sets/delegator.rb +1 -1
- data/lib/property_sets/property_set_model.rb +18 -19
- data/lib/property_sets/version.rb +1 -1
- data/lib/property_sets.rb +8 -6
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2384aedb2c9f673a4895f5a6e1948ae4ea88c335b2c79985a0c35609ebbce42e
|
4
|
+
data.tar.gz: dedff61be818879d70d720f3d7bfc545e0b73abeecaf57f678be2dc10a64d5e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9487f344c48e602edd77c4c36f9e5a4932db43cdc543efc68450d56a1fa433bcade00f1f88ac98ff452e4919865295fdbb9cb4e204ff7edd243ef16a46a28e13
|
7
|
+
data.tar.gz: a0223c6d67884a49a5165f5db027e02077d83bf094e563595f8e83d3c95c055312d46ec4b036da08c60c55e3e7f90a22b3265a940ff47f2aee4e650e9cb811a3
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "action_view"
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
module Helpers
|
@@ -8,9 +8,9 @@ module ActionView
|
|
8
8
|
|
9
9
|
def initialize(property_set, template, object_name, object)
|
10
10
|
@property_set = property_set
|
11
|
-
@template
|
12
|
-
@object_name
|
13
|
-
@object
|
11
|
+
@template = template
|
12
|
+
@object_name = object_name
|
13
|
+
@object = object
|
14
14
|
end
|
15
15
|
|
16
16
|
def check_box(property, options = {}, checked_value = "1", unchecked_value = "0")
|
@@ -23,7 +23,7 @@ module ActionView
|
|
23
23
|
def radio_button(property, checked_value = "1", options = {})
|
24
24
|
options[:id] ||= "#{object_name}_#{property_set}_#{property}_#{checked_value}"
|
25
25
|
options = prepare_options(property, options) do |properties|
|
26
|
-
properties.send(
|
26
|
+
properties.send(property.to_s) == checked_value
|
27
27
|
end
|
28
28
|
template.radio_button(object_name, property, checked_value, options)
|
29
29
|
end
|
@@ -34,7 +34,7 @@ module ActionView
|
|
34
34
|
|
35
35
|
def hidden_field(property, options = {})
|
36
36
|
options = prepare_id_name(property, options)
|
37
|
-
unless options.
|
37
|
+
unless options.key?(:value)
|
38
38
|
options[:value] = cast_boolean(options[:object].send(property_set).send(property))
|
39
39
|
end
|
40
40
|
template.hidden_field(object_name, property, options)
|
@@ -43,7 +43,7 @@ module ActionView
|
|
43
43
|
def select(property, choices, options = {}, html_options = {})
|
44
44
|
options = prepare_id_name(property, options)
|
45
45
|
current_value = options[:object].send(property_set).send(property)
|
46
|
-
template.select("#{object_name}[#{property_set}]", property, choices, {
|
46
|
+
template.select("#{object_name}[#{property_set}]", property, choices, {selected: current_value}, html_options)
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
@@ -52,9 +52,9 @@ module ActionView
|
|
52
52
|
throw "Invalid options type #{options.inspect}" unless options.is_a?(Hash)
|
53
53
|
|
54
54
|
options.clone.tap do |prepared_options|
|
55
|
-
prepared_options[:object]
|
56
|
-
prepared_options[:id]
|
57
|
-
prepared_options[:name]
|
55
|
+
prepared_options[:object] = object || fetch_target_object
|
56
|
+
prepared_options[:id] ||= "#{object_name}_#{property_set}_#{property}"
|
57
|
+
prepared_options[:name] = "#{object_name}[#{property_set}][#{property}]"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -75,18 +75,16 @@ module ActionView
|
|
75
75
|
|
76
76
|
def cast_boolean(value)
|
77
77
|
case value
|
78
|
-
when TrueClass
|
79
|
-
when FalseClass then
|
78
|
+
when TrueClass then "1"
|
79
|
+
when FalseClass then "0"
|
80
80
|
else value
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
84
83
|
end
|
85
84
|
|
86
85
|
def property_set(identifier)
|
87
86
|
PropertySetFormBuilderProxy.new(identifier, @template, object_name, object)
|
88
87
|
end
|
89
|
-
|
90
88
|
end
|
91
89
|
end
|
92
90
|
end
|
@@ -1,26 +1,27 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'set'
|
1
|
+
require "active_record"
|
2
|
+
require "property_sets/casting"
|
4
3
|
|
5
4
|
module PropertySets
|
6
5
|
module ActiveRecordExtension
|
7
6
|
module ClassMethods
|
7
|
+
attr_accessor :property_sets_connection_class
|
8
|
+
|
8
9
|
def property_set(association, options = {}, &block)
|
9
10
|
unless include?(PropertySets::ActiveRecordExtension::InstanceMethods)
|
10
|
-
|
11
|
+
send(:prepend, PropertySets::ActiveRecordExtension::InstanceMethods)
|
11
12
|
cattr_accessor :property_set_index
|
12
13
|
self.property_set_index = Set.new
|
13
14
|
end
|
14
15
|
|
15
|
-
raise "Invalid association name, letters only" unless
|
16
|
+
raise "Invalid association name, letters only" unless /[a-z]+/.match?(association.to_s)
|
16
17
|
exists = property_set_index.include?(association)
|
17
18
|
|
18
|
-
|
19
|
+
property_set_index << association
|
19
20
|
|
20
21
|
# eg AccountSetting - this IS idempotent
|
21
22
|
property_class = PropertySets.ensure_property_set_class(
|
22
23
|
association,
|
23
|
-
options.delete(:owner_class_name) ||
|
24
|
+
options.delete(:owner_class_name) || name
|
24
25
|
)
|
25
26
|
|
26
27
|
# eg property :is_awesome
|
@@ -30,17 +31,17 @@ module PropertySets
|
|
30
31
|
property_class.table_name = tb_name if tb_name
|
31
32
|
|
32
33
|
hash_opts = {
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
34
|
+
class_name: property_class.name,
|
35
|
+
autosave: true,
|
36
|
+
dependent: :destroy,
|
37
|
+
inverse_of: name.demodulize.underscore.to_sym
|
37
38
|
}.merge(options)
|
38
39
|
|
39
40
|
# TODO: should check options are compatible? warn? raise?
|
40
|
-
reflection =
|
41
|
+
reflection = reflections[association.to_s] # => ActiveRecord::Reflection::HasManyReflection
|
41
42
|
reflection.options.merge! options if reflection && !options.empty?
|
42
43
|
|
43
|
-
unless exists
|
44
|
+
unless exists # makes has_many idempotent...
|
44
45
|
has_many association, **hash_opts do
|
45
46
|
# keep this damn block! -- creates association_module below
|
46
47
|
end
|
@@ -49,23 +50,23 @@ module PropertySets
|
|
49
50
|
# stolen/adapted from AR's collection_association.rb #define_extensions
|
50
51
|
|
51
52
|
module_name = "#{association.to_s.camelize}AssociationExtension"
|
52
|
-
association_module =
|
53
|
+
association_module = const_get module_name
|
53
54
|
|
54
55
|
association_module.module_eval do
|
55
56
|
include PropertySets::ActiveRecordExtension::AssociationExtensions
|
56
57
|
|
57
58
|
property_class.keys.each do |key|
|
58
|
-
raise "Invalid property key #{key}" if
|
59
|
+
raise "Invalid property key #{key}" if respond_to?(key)
|
59
60
|
|
60
61
|
# Reports the coerced truth value of the property
|
61
62
|
define_method "#{key}?" do
|
62
|
-
type
|
63
|
+
type = property_class.type(key)
|
63
64
|
value = lookup_value(type, key)
|
64
|
-
![
|
65
|
+
!["false", "0", "", "off", "n"].member?(value.to_s.downcase)
|
65
66
|
end
|
66
67
|
|
67
68
|
# Returns the value of the property
|
68
|
-
define_method
|
69
|
+
define_method key.to_s do
|
69
70
|
type = property_class.type(key)
|
70
71
|
lookup_value(type, key)
|
71
72
|
end
|
@@ -98,10 +99,10 @@ module PropertySets
|
|
98
99
|
association_class.keys & keys.map(&:to_s)
|
99
100
|
end
|
100
101
|
|
101
|
-
property_pairs = property_keys.
|
102
|
+
property_pairs = property_keys.flat_map do |name|
|
102
103
|
value = lookup_value(association_class.type(name), name)
|
103
104
|
[name, value]
|
104
|
-
end
|
105
|
+
end
|
105
106
|
HashWithIndifferentAccess[*property_pairs]
|
106
107
|
end
|
107
108
|
|
@@ -138,7 +139,7 @@ module PropertySets
|
|
138
139
|
end
|
139
140
|
|
140
141
|
def build_default(arg)
|
141
|
-
build(:
|
142
|
+
build(name: arg.to_s, value: association_class.raw_default(arg))
|
142
143
|
end
|
143
144
|
|
144
145
|
def lookup_without_default(arg)
|
@@ -148,7 +149,7 @@ module PropertySets
|
|
148
149
|
def lookup_value(type, key)
|
149
150
|
serialized = property_serialized?(key)
|
150
151
|
|
151
|
-
if instance = lookup_without_default(key)
|
152
|
+
if (instance = lookup_without_default(key))
|
152
153
|
instance.value_serialized = serialized
|
153
154
|
PropertySets::Casting.read(type, instance.value)
|
154
155
|
else
|
@@ -163,7 +164,7 @@ module PropertySets
|
|
163
164
|
|
164
165
|
# The finder method which returns the property if present, otherwise a new instance with defaults
|
165
166
|
def lookup(arg)
|
166
|
-
instance
|
167
|
+
instance = lookup_without_default(arg)
|
167
168
|
instance ||= build_default(arg)
|
168
169
|
instance.value_serialized = property_serialized?(arg)
|
169
170
|
|
@@ -177,7 +178,7 @@ module PropertySets
|
|
177
178
|
# It does not have the side effect of adding a new setting object.
|
178
179
|
def lookup_or_default(arg)
|
179
180
|
instance = lookup_without_default(arg)
|
180
|
-
instance ||= association_class.new(:
|
181
|
+
instance ||= association_class.new(value: association_class.raw_default(arg))
|
181
182
|
instance.value_serialized = property_serialized?(arg)
|
182
183
|
instance
|
183
184
|
end
|
@@ -192,18 +193,18 @@ module PropertySets
|
|
192
193
|
update_property_set_attributes(attributes)
|
193
194
|
super
|
194
195
|
end
|
195
|
-
|
196
|
+
alias_method :update_attributes, :update
|
196
197
|
|
197
198
|
def update!(attributes)
|
198
199
|
update_property_set_attributes(attributes)
|
199
200
|
super
|
200
201
|
end
|
201
|
-
|
202
|
+
alias_method :update_attributes!, :update!
|
202
203
|
|
203
204
|
def update_property_set_attributes(attributes)
|
204
205
|
if attributes && self.class.property_set_index.any?
|
205
206
|
self.class.property_set_index.each do |property_set|
|
206
|
-
if property_set_hash = attributes.delete(property_set)
|
207
|
+
if (property_set_hash = attributes.delete(property_set))
|
207
208
|
send(property_set).set(property_set_hash, true)
|
208
209
|
end
|
209
210
|
end
|
@@ -212,7 +213,7 @@ module PropertySets
|
|
212
213
|
|
213
214
|
def update_columns(attributes)
|
214
215
|
if delegated_property_sets?
|
215
|
-
attributes = attributes.reject{|k,_| self.class.delegated_property_set_attributes.include?(k.to_s) }
|
216
|
+
attributes = attributes.reject { |k, _| self.class.delegated_property_set_attributes.include?(k.to_s) }
|
216
217
|
end
|
217
218
|
|
218
219
|
super attributes
|
@@ -239,7 +240,6 @@ module PropertySets
|
|
239
240
|
attribute_names
|
240
241
|
end
|
241
242
|
end
|
242
|
-
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
|
3
3
|
module PropertySets
|
4
4
|
module Casting
|
5
|
-
|
5
|
+
FALSE_VALUES = ["false", "0", "", "off", "n"]
|
6
6
|
|
7
7
|
class << self
|
8
8
|
def read(type, value)
|
@@ -53,7 +53,7 @@ module PropertySets
|
|
53
53
|
private
|
54
54
|
|
55
55
|
def false?(value)
|
56
|
-
|
56
|
+
FALSE_VALUES.include?(value.to_s.downcase)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -65,7 +65,7 @@ module PropertySets
|
|
65
65
|
# These are not database columns and should not be included in queries but
|
66
66
|
# using the attributes API is the only way to track changes in the main model
|
67
67
|
if respond_to?(:user_provided_columns)
|
68
|
-
|
68
|
+
user_provided_columns.reject! { |k, _| delegated_property_set_attributes.include?(k.to_s) }
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require
|
1
|
+
require "active_support"
|
2
2
|
|
3
3
|
module PropertySets
|
4
4
|
module PropertySetModel
|
5
5
|
# https://dev.mysql.com/doc/refman/5.6/en/storage-requirements.html
|
6
6
|
COLUMN_TYPE_LIMITS = {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
"tinyblob" => 255, # 2^8 - 1
|
8
|
+
"tinytext" => 255,
|
9
|
+
"blob" => 65535, # 2^16 - 1
|
10
|
+
"text" => 65535,
|
11
|
+
"mediumblob" => 16777215, # 2^24 - 1
|
12
|
+
"mediumtext" => 16777215,
|
13
|
+
"longblob" => 4294967295, # 2^32 - 1
|
14
|
+
"longtext" => 4294967295
|
15
15
|
}.freeze
|
16
16
|
|
17
17
|
module InstanceMethods
|
18
18
|
def false?
|
19
|
-
[
|
19
|
+
["false", "0", "", "off", "n"].member?(value.to_s.downcase)
|
20
20
|
end
|
21
21
|
|
22
22
|
def true?
|
@@ -93,7 +93,7 @@ module PropertySets
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def value_column_limit
|
96
|
-
column = self.class.columns_hash.fetch(
|
96
|
+
column = self.class.columns_hash.fetch("value")
|
97
97
|
|
98
98
|
# use sql_type because type returns :text for all text types regardless of length
|
99
99
|
column.limit || COLUMN_TYPE_LIMITS.fetch(column.sql_type)
|
@@ -102,9 +102,9 @@ module PropertySets
|
|
102
102
|
|
103
103
|
module ClassMethods
|
104
104
|
def self.extended(base)
|
105
|
-
base.validate
|
106
|
-
base.validate
|
107
|
-
base.before_create
|
105
|
+
base.validate :validate_format_of_name
|
106
|
+
base.validate :validate_length_of_serialized_data
|
107
|
+
base.before_create :coerce_value
|
108
108
|
base.attr_accessible :name, :value if defined?(ProtectedAttributes)
|
109
109
|
end
|
110
110
|
|
@@ -139,10 +139,10 @@ module PropertySets
|
|
139
139
|
def owner_class=(owner_class_name)
|
140
140
|
@owner_class_sym = owner_class_name.to_s.demodulize.underscore.to_sym
|
141
141
|
|
142
|
-
belongs_to
|
143
|
-
validates_presence_of
|
144
|
-
validates_uniqueness_of :name, :
|
145
|
-
attr_accessible
|
142
|
+
belongs_to owner_class_sym, class_name: owner_class_name
|
143
|
+
validates_presence_of owner_class_sym, class_name: owner_class_name
|
144
|
+
validates_uniqueness_of :name, scope: owner_class_key_sym, case_sensitive: false
|
145
|
+
attr_accessible owner_class_key_sym, owner_class_sym if defined?(ProtectedAttributes)
|
146
146
|
end
|
147
147
|
|
148
148
|
def owner_assoc=(association)
|
@@ -161,6 +161,5 @@ module PropertySets
|
|
161
161
|
"#{owner_class_sym}_id".to_sym
|
162
162
|
end
|
163
163
|
end
|
164
|
-
|
165
164
|
end
|
166
165
|
end
|
data/lib/property_sets.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "property_sets/property_set_model"
|
2
|
+
require "property_sets/active_record_extension"
|
3
|
+
require "property_sets/version"
|
4
4
|
|
5
5
|
begin
|
6
|
-
require
|
6
|
+
require "property_sets/action_view_extension"
|
7
7
|
rescue LoadError
|
8
8
|
end
|
9
9
|
|
@@ -19,7 +19,7 @@ module PropertySets
|
|
19
19
|
unless namespace.const_defined?(const_name, false)
|
20
20
|
property_class = Class.new(parent_for_property_class(namespace, owner_class_name)) do
|
21
21
|
include PropertySets::PropertySetModel::InstanceMethods
|
22
|
-
extend
|
22
|
+
extend PropertySets::PropertySetModel::ClassMethods
|
23
23
|
end
|
24
24
|
|
25
25
|
namespace.const_set(const_name, property_class)
|
@@ -32,7 +32,9 @@ module PropertySets
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.parent_for_property_class(namespace, owner_class_name)
|
35
|
-
namespace.const_get(owner_class_name)
|
35
|
+
owner_class = namespace.const_get(owner_class_name)
|
36
|
+
|
37
|
+
owner_class.property_sets_connection_class || owner_class.connection_class_for_self
|
36
38
|
rescue NameError
|
37
39
|
::ActiveRecord::Base
|
38
40
|
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.
|
4
|
+
version: 3.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Morten Primdahl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -100,6 +100,20 @@ dependencies:
|
|
100
100
|
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: standard
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: byebug
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|