slim_form_object 1.0.9 → 2.0.1
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/slim_form_object/assign.rb +110 -41
- data/lib/slim_form_object/form_helpers/extension_actionview.rb +82 -38
- data/lib/slim_form_object/helpers.rb +34 -25
- data/lib/slim_form_object/processing.rb +22 -16
- data/lib/slim_form_object/saver.rb +8 -34
- data/lib/slim_form_object/validator.rb +12 -32
- data/lib/slim_form_object/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04280a1e4b59f8a5224e87f366b154f115bda997
|
4
|
+
data.tar.gz: 8836e2dc9690a4a5cd23e01b8f318e99102f0df8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91ad831f0f9bb4419b678d7562485aabc731727d2453d494e1616994d6213bbffa75ccfb87d925de6508ab4c34be3a3d4c41ab8a9800bbff6699c7d5365545d5
|
7
|
+
data.tar.gz: 54d9b311c4fbbceba212b2b558b08bef28eb835b1aa1b0f02b6df6fc478f65b1ff7555a709d0d61cc757f9113f72c968b4172da3f27f8bb856374b52c02ed14f
|
@@ -2,73 +2,142 @@ module SlimFormObject
|
|
2
2
|
class Assign
|
3
3
|
include ::HelperMethods
|
4
4
|
|
5
|
-
attr_reader :form_object, :params, :
|
5
|
+
attr_reader :form_object, :params, :all_updated_objects, :base_module, :validator
|
6
6
|
|
7
7
|
def initialize(form_object)
|
8
8
|
@form_object = form_object
|
9
|
+
@base_module = form_object.class.base_module
|
9
10
|
@params = form_object.params
|
10
11
|
@array_all_objects_for_save = form_object.array_all_objects_for_save
|
11
|
-
@
|
12
|
+
@validator = Validator.new(form_object)
|
13
|
+
@all_updated_objects = []
|
12
14
|
end
|
13
15
|
|
14
16
|
def apply_parameters
|
15
|
-
|
16
|
-
|
17
|
+
make_all_objects_with_attributes
|
18
|
+
clear_nil_objects
|
17
19
|
|
18
|
-
|
20
|
+
all_updated_objects
|
21
|
+
end
|
22
|
+
|
23
|
+
def associate_objects
|
24
|
+
associate_all_objects(all_updated_objects)
|
25
|
+
|
26
|
+
all_updated_objects
|
19
27
|
end
|
20
28
|
|
21
29
|
private
|
22
30
|
|
23
|
-
|
31
|
+
def clear_nil_objects
|
32
|
+
arr_ids_nil_object = []
|
33
|
+
find_ids_nil_object(arr_ids_nil_object, all_updated_objects)
|
34
|
+
delete_hash_nil_objects(arr_ids_nil_object, all_updated_objects)
|
35
|
+
end
|
24
36
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
37
|
+
def delete_hash_nil_objects(ids_arr, nested_array)
|
38
|
+
nested_array.select!{|e| !ids_arr.include?(e.object_id)}
|
39
|
+
nested_array.each do |hash|
|
40
|
+
delete_hash_nil_objects(ids_arr, hash[:nested])
|
28
41
|
end
|
42
|
+
end
|
29
43
|
|
30
|
-
|
44
|
+
def find_ids_nil_object(ids_arr, nested_array)
|
45
|
+
nested_array.each do |hash|
|
46
|
+
ids_arr << hash.object_id if !validator.save_if_object_is_empty?(hash[:essence][:object])
|
47
|
+
find_ids_nil_object(ids_arr, hash[:nested])
|
48
|
+
end
|
31
49
|
end
|
32
50
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
{}
|
51
|
+
def associate_all_objects(nested_array, object=nil)
|
52
|
+
nested_array.each do |hash|
|
53
|
+
to_bind_models(object, hash[:essence][:object]) if object
|
54
|
+
associate_all_objects(hash[:nested], hash[:essence][:object])
|
38
55
|
end
|
39
56
|
end
|
40
57
|
|
41
|
-
def
|
42
|
-
|
43
|
-
params.
|
44
|
-
|
58
|
+
def make_all_objects_with_attributes
|
59
|
+
object_hash = {}
|
60
|
+
params.each do |main_model_name, hash|
|
61
|
+
assign_objects_attributes(main_model_name, hash, object_hash, @all_updated_objects)
|
62
|
+
end
|
45
63
|
end
|
46
64
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
end
|
65
|
+
def nested(model_name, nested_array, result_array)
|
66
|
+
object_hash = {}
|
67
|
+
nested_array.each do |nested_object|
|
68
|
+
assign_objects_attributes(model_name, nested_object, object_hash, result_array)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def is_nested?(value)
|
73
|
+
return false unless value.class == Array
|
74
|
+
value.select{ |e| e.class == ActionController::Parameters or e.class == Hash }.size == value.size
|
75
|
+
end
|
76
|
+
|
77
|
+
def assign_objects_attributes(model_name, hash, object_hash, result_array)
|
78
|
+
object = get_class_of_snake_model_name(model_name).new
|
79
|
+
object_hash[:nested] = []
|
80
|
+
hash.each do |key, val|
|
81
|
+
if is_nested?(val)
|
82
|
+
nested(key, val, object_hash[:nested])
|
83
|
+
else
|
84
|
+
object.assign_attributes({"#{key}": val})
|
69
85
|
end
|
70
86
|
end
|
87
|
+
object_hash[:essence] = {model: model_name, object: object}
|
88
|
+
result_array << object_hash
|
71
89
|
end
|
90
|
+
|
91
|
+
|
92
|
+
# def force_permit(params)
|
93
|
+
# return nil if params.class != ActionController::Parameters
|
94
|
+
# params.instance_variable_set(:@permitted, true)
|
95
|
+
# params
|
96
|
+
# end
|
97
|
+
|
98
|
+
# PARAMS FORMAT
|
99
|
+
# {
|
100
|
+
# "user"=> {
|
101
|
+
# "email"=>"kjbkj@bk.ddd",
|
102
|
+
# "password"=>"dsmndvvs",
|
103
|
+
# "password_confirmation"=>"jvdjshvd",
|
104
|
+
# "address_user"=> [
|
105
|
+
# {
|
106
|
+
# "first_name"=>"dsdsd",
|
107
|
+
# "last_name"=>"kjhkjbk",
|
108
|
+
# "order"=> [
|
109
|
+
# {
|
110
|
+
# "created_at"=>"kjkjb",
|
111
|
+
# "updated_at"=>"kjbkjb"
|
112
|
+
# }
|
113
|
+
# ]
|
114
|
+
# }
|
115
|
+
# ]
|
116
|
+
# }
|
117
|
+
# }
|
118
|
+
|
119
|
+
# make_all_objects_with_attributes() EXAMPLE @all_updated_objects FORMAT
|
120
|
+
#
|
121
|
+
# [
|
122
|
+
# {
|
123
|
+
# essence: {model: 'user', object: WoodShop::User.new(attributes)},
|
124
|
+
# nested: [
|
125
|
+
# {
|
126
|
+
# essence: {model: 'address_user', object: WoodShop::AddressUser.new(attributes)},
|
127
|
+
# nested: [
|
128
|
+
# {
|
129
|
+
# essence: {model: 'image', object: WoodShop::Image.new(attributes)},
|
130
|
+
# nested: []
|
131
|
+
# },
|
132
|
+
# {
|
133
|
+
# essence: {model: 'image', object: WoodShop::Image.new(attributes)},
|
134
|
+
# nested: []
|
135
|
+
# }
|
136
|
+
# ]
|
137
|
+
# }
|
138
|
+
# ]
|
139
|
+
# }
|
140
|
+
# ]
|
72
141
|
end
|
73
142
|
end
|
74
143
|
|
@@ -1,17 +1,6 @@
|
|
1
1
|
module ActionView
|
2
2
|
module Helpers
|
3
3
|
module HelperMethods
|
4
|
-
def sfo_fields_for(name, object = nil, form_options: {}, options: {}, &block)
|
5
|
-
object = get_class_of_snake_model_name(name.to_s).new unless object
|
6
|
-
|
7
|
-
if options[:sfo_form]
|
8
|
-
form_object_class = get_class_of_snake_model_name(name.to_s)
|
9
|
-
name = "slim_form_object_#{name}"
|
10
|
-
object = form_object_class.new(form_options)
|
11
|
-
end
|
12
|
-
|
13
|
-
fields_for(name, object, options, &block)
|
14
|
-
end
|
15
4
|
|
16
5
|
private
|
17
6
|
|
@@ -23,10 +12,6 @@ module ActionView
|
|
23
12
|
/^([^-]+)-([^-]+)$/
|
24
13
|
end
|
25
14
|
|
26
|
-
def sfo_multiple_attr_regexp
|
27
|
-
/sfo-multiple/
|
28
|
-
end
|
29
|
-
|
30
15
|
def sfo_date_attr_regexp
|
31
16
|
/^([^-]+)-([^-]+)(\([\s\S]+\))$/
|
32
17
|
end
|
@@ -40,17 +25,13 @@ module ActionView
|
|
40
25
|
end
|
41
26
|
|
42
27
|
def sfo_attr?(method)
|
43
|
-
sfo_single_attr?(method)
|
28
|
+
sfo_single_attr?(method)
|
44
29
|
end
|
45
30
|
|
46
31
|
def sfo_single_attr?(method)
|
47
32
|
method.to_s[sfo_single_attr_regexp] ? true : false
|
48
33
|
end
|
49
34
|
|
50
|
-
def sfo_multiple_attr?(string)
|
51
|
-
string.to_s[sfo_multiple_attr_regexp] ? true : false
|
52
|
-
end
|
53
|
-
|
54
35
|
def sfo_date_attr?(tag_name)
|
55
36
|
tag_name.to_s[sfo_date_attr_regexp] ? true : false
|
56
37
|
end
|
@@ -59,11 +40,15 @@ module ActionView
|
|
59
40
|
tag_name.to_s[sfo_collection_ads_regexp] ? true : false
|
60
41
|
end
|
61
42
|
|
62
|
-
def sfo_get_tag_name(object_name, method, multiple)
|
43
|
+
def sfo_get_tag_name(object_name, method, multiple, options)
|
63
44
|
model_name, attr_name = apply_expression_text(method, sfo_single_attr_regexp)
|
64
45
|
|
65
|
-
if
|
66
|
-
|
46
|
+
if options[:sfo_nested]
|
47
|
+
if options[:sfo_main]
|
48
|
+
tag_name = "#{object_name}[#{model_name}][][#{attr_name}]#{"[]" if multiple}"
|
49
|
+
else
|
50
|
+
tag_name = "#{object_name}[][#{model_name}][][#{attr_name}]#{"[]" if multiple}"
|
51
|
+
end
|
67
52
|
elsif sfo_single_attr?(method)
|
68
53
|
tag_name = "#{object_name}[#{model_name}][#{attr_name}]#{"[]" if multiple}"
|
69
54
|
end
|
@@ -80,10 +65,10 @@ module ActionView
|
|
80
65
|
method
|
81
66
|
end
|
82
67
|
|
83
|
-
def sfo_get_date_tag_name(prefix, tag_name)
|
68
|
+
def sfo_get_date_tag_name(prefix, tag_name, options)
|
84
69
|
model_name, attr_name, date_type = apply_expression_date(tag_name, sfo_date_attr_regexp)
|
85
70
|
|
86
|
-
if
|
71
|
+
if options[:sfo_nested]
|
87
72
|
tag_name = "#{prefix}[#{model_name}][][#{attr_name}#{date_type}]"
|
88
73
|
else
|
89
74
|
tag_name = "#{prefix}[#{model_name}][#{attr_name}#{date_type}]"
|
@@ -110,6 +95,9 @@ module ActionView
|
|
110
95
|
end
|
111
96
|
end
|
112
97
|
|
98
|
+
|
99
|
+
# EXTENSIONS
|
100
|
+
|
113
101
|
class DateTimeSelector
|
114
102
|
include HelperMethods
|
115
103
|
|
@@ -121,8 +109,8 @@ module ActionView
|
|
121
109
|
if @options[:include_position]
|
122
110
|
field_name += "(#{ActionView::Helpers::DateTimeSelector::POSITION[type]}i)"
|
123
111
|
end
|
124
|
-
|
125
|
-
return sfo_get_date_tag_name(prefix, field_name) if sfo_date_attr?(field_name)
|
112
|
+
options = self.instance_variable_get(:@options)
|
113
|
+
return sfo_get_date_tag_name(prefix, field_name, options) if sfo_date_attr?(field_name)
|
126
114
|
|
127
115
|
@options[:discard_type] ? prefix : "#{prefix}[#{field_name}]"
|
128
116
|
|
@@ -141,7 +129,8 @@ module ActionView
|
|
141
129
|
end
|
142
130
|
|
143
131
|
def tag_name(multiple = false, index = nil)
|
144
|
-
|
132
|
+
options = self.instance_variable_get(:@options)
|
133
|
+
return sfo_get_tag_name(@object_name, sanitized_method_name, multiple, options) if sfo_attr?(sanitized_method_name)
|
145
134
|
|
146
135
|
if index
|
147
136
|
"#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]" if multiple}"
|
@@ -154,21 +143,76 @@ module ActionView
|
|
154
143
|
|
155
144
|
class FormBuilder
|
156
145
|
include HelperMethods
|
146
|
+
|
147
|
+
def initialize(object_name, object, template, options)
|
148
|
+
@nested_child_index = {}
|
149
|
+
@object_name, @object, @template, @options = object_name, object, template, options
|
150
|
+
@default_options = @options ? @options.slice(:index, :namespace, :skip_default_ids, :allow_method_names_outside_object) : {}
|
151
|
+
@default_options.merge!( {sfo_nested: options[:sfo_nested], sfo_main: options[:sfo_main]} )
|
152
|
+
convert_to_legacy_options(@options)
|
153
|
+
|
154
|
+
if @object_name.to_s.match(/\[\]$/)
|
155
|
+
if (object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
|
156
|
+
@auto_index = object.to_param
|
157
|
+
else
|
158
|
+
raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
@multipart = nil
|
163
|
+
@index = options[:index] || options[:child_index]
|
164
|
+
end
|
165
|
+
|
166
|
+
def fields_for(record_name, record_object = nil, fields_options = {}, &block)
|
167
|
+
(self.options[:sfo_nested] and record_object) ? record_object.merge!({sfo_main: false}) : record_object.merge!({sfo_main: true})
|
168
|
+
fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
|
169
|
+
fields_options[:builder] ||= options[:builder]
|
170
|
+
fields_options[:namespace] = options[:namespace]
|
171
|
+
fields_options[:parent_builder] = self
|
172
|
+
|
173
|
+
case record_name
|
174
|
+
when String, Symbol
|
175
|
+
if nested_attributes_association?(record_name)
|
176
|
+
return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
record_object = record_name.is_a?(Array) ? record_name.last : record_name
|
180
|
+
record_name = model_name_from_record_or_class(record_object).param_key
|
181
|
+
end
|
182
|
+
|
183
|
+
object_name = @object_name
|
184
|
+
index = if options.has_key?(:index)
|
185
|
+
options[:index]
|
186
|
+
elsif defined?(@auto_index)
|
187
|
+
object_name = object_name.to_s.sub(/\[\]$/, "")
|
188
|
+
@auto_index
|
189
|
+
end
|
190
|
+
|
191
|
+
record_name = if index
|
192
|
+
"#{object_name}[#{index}][#{record_name}]"
|
193
|
+
elsif record_name.to_s.end_with?("[]")
|
194
|
+
record_name = record_name.to_s.sub(/(.*)\[\]$/, "[\\1][#{record_object.id}]")
|
195
|
+
"#{object_name}#{record_name}"
|
196
|
+
else
|
197
|
+
"#{object_name}[#{record_name}]"
|
198
|
+
end
|
199
|
+
fields_options[:child_index] = index
|
200
|
+
|
201
|
+
if fields_options[:sfo_nested]
|
202
|
+
record_object = object
|
203
|
+
record_name = record_name + '[]'
|
204
|
+
end
|
205
|
+
@template.fields_for(record_name, record_object, fields_options, &block)
|
206
|
+
end
|
157
207
|
end
|
158
208
|
|
159
209
|
module FormHelper
|
160
210
|
include HelperMethods
|
161
211
|
|
162
|
-
def fields_for(record_name, record_object = nil, options = {}, &block)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
part_2 = $2
|
167
|
-
record_name = "#{part_1}[sfo-multiple]#{part_2}"
|
168
|
-
end
|
169
|
-
builder = instantiate_builder(record_name, record_object, options)
|
170
|
-
capture(builder, &block)
|
171
|
-
end
|
212
|
+
# def fields_for(record_name, record_object = nil, options = {}, &block)
|
213
|
+
# builder = instantiate_builder(record_name, record_object, options)
|
214
|
+
# capture(builder, &block)
|
215
|
+
# end
|
172
216
|
end
|
173
217
|
|
174
218
|
end
|
@@ -1,35 +1,15 @@
|
|
1
1
|
module HelperMethods
|
2
|
-
def snake(string)
|
3
|
-
string = string.to_s
|
4
|
-
string.gsub!(/((\w)([A-Z]))/,'\2_\3')
|
5
|
-
class_name_if_module(string.downcase)
|
6
|
-
end
|
7
|
-
|
8
|
-
def class_name_if_module(string)
|
9
|
-
return $1 if string =~ /^.+::(.+)$/
|
10
|
-
string
|
11
|
-
end
|
12
|
-
|
13
2
|
def get_self_object(model)
|
14
3
|
method( snake(model.to_s).to_sym ).call
|
15
4
|
end
|
16
5
|
|
17
6
|
def get_class_of_snake_model_name(snake_model_name)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
if sfo_single_attr?(method)
|
23
|
-
apply_expression_text(method, sfo_single_attr_regexp)
|
7
|
+
pref = if self.base_module
|
8
|
+
self.base_module.to_s + '::'
|
9
|
+
else
|
10
|
+
''
|
24
11
|
end
|
25
|
-
|
26
|
-
|
27
|
-
def sfo_single_attr?(method)
|
28
|
-
method.to_s[sfo_single_attr_regexp] ? true : false
|
29
|
-
end
|
30
|
-
|
31
|
-
def sfo_single_attr_regexp
|
32
|
-
/^([^-]+)-([^-]+)$/
|
12
|
+
Object.const_get( pref + snake_model_name.to_s.split('_').map(&:capitalize).join )
|
33
13
|
end
|
34
14
|
|
35
15
|
def apply_expression_text(string, exp)
|
@@ -39,4 +19,33 @@ module HelperMethods
|
|
39
19
|
|
40
20
|
[model_name, attr_name]
|
41
21
|
end
|
22
|
+
|
23
|
+
def snake(string)
|
24
|
+
string = string.to_s
|
25
|
+
string.gsub!(/((\w)([A-Z]))/,'\2_\3')
|
26
|
+
class_name_if_module(string.downcase)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_bind_models(object_1, object_2)
|
30
|
+
association = get_association(object_1.class, object_2.class)
|
31
|
+
|
32
|
+
if association == :belongs_to or association == :has_one
|
33
|
+
object_1.send( "#{snake(object_2.class.to_s)}=", object_2 )
|
34
|
+
elsif association == :has_many or association == :has_and_belongs_to_many
|
35
|
+
object_1.method("#{object_2.class.table_name}").call << object_2
|
36
|
+
end
|
37
|
+
|
38
|
+
object_1
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_association(class1, class2)
|
42
|
+
class1.reflections.slice(snake(class2.to_s), class2.table_name).values.first&.macro
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def class_name_if_module(string)
|
48
|
+
return $1 if string =~ /^.+::(.+)$/
|
49
|
+
string
|
50
|
+
end
|
42
51
|
end
|
@@ -4,9 +4,11 @@ module SlimFormObject
|
|
4
4
|
include ::HelperMethods
|
5
5
|
extend ::HelperMethods
|
6
6
|
|
7
|
-
attr_accessor :params, :array_objects_for_save, :
|
7
|
+
attr_accessor :params, :array_objects_for_save, :data_for_save
|
8
8
|
|
9
9
|
class << self
|
10
|
+
attr_accessor :base_module
|
11
|
+
|
10
12
|
def set_model_name(name)
|
11
13
|
define_method(:model_name) { ActiveModel::Name.new(self, nil, name) }
|
12
14
|
end
|
@@ -45,18 +47,12 @@ module SlimFormObject
|
|
45
47
|
end
|
46
48
|
|
47
49
|
# CALLBACKS
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
def after_save_form(&block)
|
57
|
-
if block_given?
|
58
|
-
self.instance_eval do
|
59
|
-
define_method(:after_save_block) { block }
|
50
|
+
%w(after_initialize before_save after_save before_validation after_validation).each do |method_name|
|
51
|
+
define_singleton_method("#{method_name}_form".to_sym) do |&block|
|
52
|
+
if block_given?
|
53
|
+
self.instance_eval do
|
54
|
+
define_method("#{method_name}_block".to_sym) { block }
|
55
|
+
end
|
60
56
|
end
|
61
57
|
end
|
62
58
|
end
|
@@ -75,11 +71,12 @@ module SlimFormObject
|
|
75
71
|
require_extensions
|
76
72
|
self.params = params
|
77
73
|
get_or_add_default_objects
|
74
|
+
default_settings
|
75
|
+
self.after_initialize_block.call(self)
|
78
76
|
end
|
79
77
|
# END INIT
|
80
78
|
|
81
79
|
def apply_parameters
|
82
|
-
default_settings
|
83
80
|
apply
|
84
81
|
self
|
85
82
|
end
|
@@ -89,8 +86,13 @@ module SlimFormObject
|
|
89
86
|
Saver.new(self).save
|
90
87
|
end
|
91
88
|
|
89
|
+
def save
|
90
|
+
Saver.new(self).save!
|
91
|
+
end
|
92
|
+
|
92
93
|
def validation_models
|
93
94
|
Validator.new(self).validate_form_object
|
95
|
+
# self.after_validation_block.call(self)
|
94
96
|
end
|
95
97
|
|
96
98
|
def array_all_objects_for_save
|
@@ -105,7 +107,8 @@ module SlimFormObject
|
|
105
107
|
|
106
108
|
def apply
|
107
109
|
assign = Assign.new(self)
|
108
|
-
@
|
110
|
+
@data_for_save = assign.apply_parameters
|
111
|
+
@data_for_save = assign.associate_objects
|
109
112
|
end
|
110
113
|
|
111
114
|
def get_or_add_default_objects
|
@@ -120,8 +123,11 @@ module SlimFormObject
|
|
120
123
|
|
121
124
|
def default_settings
|
122
125
|
define_singleton_method(:array_models_which_not_save_if_empty) { [] } unless respond_to?(:array_models_which_not_save_if_empty)
|
123
|
-
define_singleton_method(:
|
126
|
+
define_singleton_method(:after_initialize_block) { Proc.new {} } unless respond_to?(:after_initialize_block)
|
124
127
|
define_singleton_method(:before_save_block) { Proc.new {} } unless respond_to?(:before_save_block)
|
128
|
+
define_singleton_method(:after_save_block) { Proc.new {} } unless respond_to?(:after_save_block)
|
129
|
+
define_singleton_method(:before_validation_block) { Proc.new {} } unless respond_to?(:before_validation_block)
|
130
|
+
define_singleton_method(:after_validation_block) { Proc.new {} } unless respond_to?(:after_validation_block)
|
125
131
|
end
|
126
132
|
|
127
133
|
end
|
@@ -2,12 +2,13 @@ module SlimFormObject
|
|
2
2
|
class Saver
|
3
3
|
include ::HelperMethods
|
4
4
|
|
5
|
-
attr_reader :form_object, :params, :validator, :
|
5
|
+
attr_reader :form_object, :params, :validator, :base_module, :data_for_save
|
6
6
|
|
7
7
|
def initialize(form_object)
|
8
8
|
@form_object = form_object
|
9
|
+
@base_module = form_object.class.base_module
|
9
10
|
@params = form_object.params
|
10
|
-
@
|
11
|
+
@data_for_save = form_object.data_for_save
|
11
12
|
@validator = Validator.new(form_object)
|
12
13
|
end
|
13
14
|
|
@@ -34,45 +35,24 @@ module SlimFormObject
|
|
34
35
|
ActiveRecord::Base.transaction do
|
35
36
|
form_object.before_save_block.call(form_object)
|
36
37
|
save_main_objects
|
37
|
-
save_nested_objects
|
38
38
|
form_object.after_save_block.call(form_object)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def save_main_objects
|
43
|
-
objects = Array.new(
|
44
|
-
while
|
45
|
-
|
43
|
+
objects = Array.new(data_for_save)
|
44
|
+
while object = objects.delete( objects[0] )
|
45
|
+
object_1 = object[:essence][:object]
|
46
|
+
objects.each{ |hash| save_objects(object_1, hash[:essence][:object]) }
|
46
47
|
save_last_model_if_not_associations(object_1)
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
def save_nested_objects
|
51
|
-
hash_objects_for_save[:objects].each do |object_1|
|
52
|
-
next unless hash_objects_for_save[:nested_objects].include?( snake(object_1.class).to_sym )
|
53
|
-
hash_objects_for_save[:nested_objects][snake(object_1.class).to_sym].each do |object_2|
|
54
|
-
save_objects(object_1, object_2)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
51
|
def save_objects(object_1, object_2)
|
60
52
|
object_for_save = to_bind_models(object_1, object_2)
|
61
53
|
save_object(object_for_save)
|
62
54
|
end
|
63
55
|
|
64
|
-
def to_bind_models(object_1, object_2)
|
65
|
-
association = get_association(object_1.class, object_2.class)
|
66
|
-
|
67
|
-
if association == :belongs_to or association == :has_one
|
68
|
-
object_1.send( "#{snake(object_2.class.to_s)}=", object_2 )
|
69
|
-
elsif association == :has_many or association == :has_and_belongs_to_many
|
70
|
-
object_1.method("#{object_2.class.table_name}").call << object_2
|
71
|
-
end
|
72
|
-
|
73
|
-
object_1
|
74
|
-
end
|
75
|
-
|
76
56
|
def save_object(object_of_model)
|
77
57
|
if validator.valid_model_for_save?(object_of_model.class)
|
78
58
|
object_of_model.save!
|
@@ -81,14 +61,8 @@ module SlimFormObject
|
|
81
61
|
|
82
62
|
def save_last_model_if_not_associations(object_1)
|
83
63
|
association_trigger = false
|
84
|
-
|
64
|
+
data_for_save.each { |hash| association_trigger = true if get_association(object_1.class, hash[:essence][:object].class) }
|
85
65
|
object_1.save unless association_trigger
|
86
|
-
rescue
|
87
|
-
object_1.class.find(object_1.id).update!(object_1.attributes)
|
88
|
-
end
|
89
|
-
|
90
|
-
def get_association(class1, class2)
|
91
|
-
class1.reflections.slice(snake(class2.to_s), class2.table_name).values.first&.macro
|
92
66
|
end
|
93
67
|
|
94
68
|
end
|
@@ -2,48 +2,32 @@ module SlimFormObject
|
|
2
2
|
class Validator
|
3
3
|
include ::HelperMethods
|
4
4
|
|
5
|
-
attr_reader
|
5
|
+
attr_reader :form_object, :params, :array_models_which_not_save_if_empty, :base_module, :data_for_save
|
6
6
|
|
7
7
|
def initialize(form_object)
|
8
8
|
@form_object = form_object
|
9
|
+
@base_module = form_object.class.base_module
|
9
10
|
@params = form_object.params
|
10
|
-
@
|
11
|
+
@data_for_save = form_object.data_for_save
|
11
12
|
@array_models_which_not_save_if_empty = form_object.array_models_which_not_save_if_empty
|
12
13
|
end
|
13
14
|
|
14
15
|
def validate_form_object
|
15
|
-
|
16
|
-
validation_objects
|
17
|
-
|
16
|
+
form_object.before_validation_block.call(form_object)
|
17
|
+
validation_objects(data_for_save)
|
18
|
+
form_object.after_validation_block.call(form_object)
|
18
19
|
end
|
19
20
|
|
20
|
-
def
|
21
|
-
|
21
|
+
def save_if_object_is_empty?(object)
|
22
|
+
!(all_attributes_is_nil?(object) and array_models_which_not_save_if_empty.include?(object.class))
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
25
26
|
|
26
|
-
def validation_objects
|
27
|
-
|
28
|
-
set_errors( snake(object.class), object.errors ) unless object.valid?
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def validation_nested_objects
|
33
|
-
hash_objects_for_save[:nested_objects].keys.each do |snake_model_name|
|
34
|
-
hash_objects_for_save[:nested_objects][snake_model_name].each do |object|
|
35
|
-
set_errors( snake(object.class), object.errors ) unless object.valid?
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def filter_models
|
41
|
-
filter_nil_objects
|
42
|
-
end
|
43
|
-
|
44
|
-
def filter_nil_objects
|
45
|
-
hash_objects_for_save[:objects].reject! do |object|
|
46
|
-
!save_if_object_is_empty?(object)
|
27
|
+
def validation_objects(nested_array)
|
28
|
+
nested_array.each do |hash|
|
29
|
+
set_errors( snake(hash[:essence][:object].class), hash[:essence][:object].errors ) unless hash[:essence][:object].valid?
|
30
|
+
validation_objects(hash[:nested])
|
47
31
|
end
|
48
32
|
end
|
49
33
|
|
@@ -54,10 +38,6 @@ module SlimFormObject
|
|
54
38
|
true
|
55
39
|
end
|
56
40
|
|
57
|
-
def save_if_object_is_empty?(object)
|
58
|
-
!(all_attributes_is_nil?(object) and array_models_which_not_save_if_empty.include?(object.class))
|
59
|
-
end
|
60
|
-
|
61
41
|
def set_errors(object_name, object_errors)
|
62
42
|
object_errors.each do |attribute, message|
|
63
43
|
form_object.errors.add(object_name, { attribute => message})
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slim_form_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- woodcrust
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-10-
|
11
|
+
date: 2017-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
200
|
version: '0'
|
201
201
|
requirements: []
|
202
202
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.
|
203
|
+
rubygems_version: 2.5.1
|
204
204
|
signing_key:
|
205
205
|
specification_version: 4
|
206
206
|
summary: This is form object
|