slim_form_object 0.5.23 → 1.0.1

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
  SHA1:
3
- metadata.gz: c790c09a7f14bba8e6919633cf1e42b329b28e09
4
- data.tar.gz: 9a56d7be9abf5a89d75a0e1528e3f5379d1e7f93
3
+ metadata.gz: eead85525874b4ad6ac4fea0f9bdace9f2cc5f90
4
+ data.tar.gz: e382a9c9eabfcdf5744647916a6f9d68dc1e06bd
5
5
  SHA512:
6
- metadata.gz: 41588b2e3ee7615fa00c64d8bf6358f28c7ba77775247a02af54e0ce87fee09f943bbce12832677b18a3d80b87a1f2c59bb95d0c18726df11e8b3dfac82824ca
7
- data.tar.gz: 0b2adebf258a068570ab894e0e27babe9888ce33389db897b4704a98801dee89c3fac6a5dfdcff80fd7e3908fcac6b253dd4fc839f43d72e25dd89b18b68502d
6
+ metadata.gz: 65fc388efca69511b521c7c4589fdf0828f3f8ef5a6e4f4693b8bb78fc53370752e1563f1ef2692066c38b34b15d5cce7bc184d28fb7b1c4fbd9a5c356908346
7
+ data.tar.gz: c97e749fe60e6cf20a813aa9ff77ff24f68352122d863592c71d4a1cc96b06eb6eeb4146aa92353e9a7b8bb7801a7d66d50cbb4e9a8498ef7c2a8a96d9ec0203
@@ -1,7 +1,10 @@
1
1
  require "slim_form_object/version"
2
+ require "slim_form_object/form_helpers/extension_actionview"
2
3
  require "slim_form_object/helpers"
4
+ require "slim_form_object/validator"
3
5
  require "slim_form_object/processing"
6
+ require "slim_form_object/assign"
7
+ require "slim_form_object/saver"
4
8
 
5
9
  module SlimFormObject
6
-
7
10
  end
@@ -0,0 +1,89 @@
1
+ module SlimFormObject
2
+ class Assign
3
+ include ::HelperMethods
4
+
5
+ attr_reader :form_object, :params, :array_all_objects_for_save, :not_save_this_model, :result_hash_updated_objects
6
+
7
+ def initialize(form_object)
8
+ @form_object = form_object
9
+ @params = form_object.params
10
+ @array_all_objects_for_save = form_object.array_all_objects_for_save
11
+ @not_save_this_model = form_object.not_save_this_model
12
+ @result_hash_updated_objects = {objects: [], nested_objects: {}}
13
+ end
14
+
15
+ def apply_parameters
16
+ filter_not_save_objects
17
+ update_objects_attributes
18
+ make_nested_objects
19
+
20
+ result_hash_updated_objects
21
+ end
22
+
23
+ def filter_not_save_objects
24
+ array_all_objects_for_save.reject do |object|
25
+ not_save_this_model.include?(object.class)
26
+ end
27
+ end
28
+
29
+ # STANDART OBJECTS
30
+
31
+ def update_objects_attributes
32
+ array_all_objects_for_save.each do |object|
33
+ object.assign_attributes(hash_params_of_object(object))
34
+ end
35
+
36
+ result_hash_updated_objects[:objects] = array_all_objects_for_save
37
+ end
38
+
39
+
40
+ def hash_params_of_object(object)
41
+ if force_permit(params[snake(object.class.to_s)])
42
+ params[snake(object.class.to_s)]
43
+ else
44
+ {}
45
+ end
46
+ end
47
+
48
+ def force_permit(params)
49
+ return nil if params.class != ActionController::Parameters
50
+ params.instance_variable_set(:@permitted, true)
51
+ params
52
+ end
53
+
54
+ # NESTED OBJECTS
55
+ # example params
56
+ #
57
+ # "sfo-multiple"=>{
58
+ # snake_model_name "category_vacancy"=>{
59
+ # snake_object_name "specialty_vacancy"=>[
60
+ # parameters {"name"=>"4", "category_vacancy_id"=>"12"}, {"name"=>"6", "category_vacancy_id"=>"14"} ]}}
61
+ #
62
+ def make_nested_objects
63
+ params.keys.each do |key|
64
+ if key == 'sfo-multiple'
65
+ params[key].keys.each do |snake_model_name|
66
+ result_hash_updated_objects[:nested_objects][snake_model_name.to_sym] ||= []
67
+
68
+ params[key][snake_model_name].keys.each do |snake_object_name|
69
+ params[key][snake_model_name][snake_object_name].each do |parameters|
70
+ object = get_class_of_snake_model_name(snake_object_name).new
71
+ object.assign_attributes(force_permit(parameters))
72
+ result_hash_updated_objects[:nested_objects][snake_model_name.to_sym] << object
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
@@ -0,0 +1,161 @@
1
+ module ActionView
2
+ module Helpers
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
+
16
+ private
17
+
18
+ def get_class_of_snake_model_name(snake_model_name)
19
+ Object.const_get( snake_model_name.split('_').map(&:capitalize).join )
20
+ end
21
+
22
+ def sfo_single_attr_regexp
23
+ /^([^-]+)-([^-]+)$/
24
+ end
25
+
26
+ def sfo_multiple_attr_regexp
27
+ /sfo-multiple/
28
+ end
29
+
30
+ def sfo_date_attr_regexp
31
+ /^([^-]+)-([^-]+)(\([\s\S]+\))$/
32
+ end
33
+
34
+ def sfo_form_attribute?(object)
35
+ object.class.ancestors[1] == SlimFormObject::Base if object
36
+ end
37
+
38
+ def sfo_attr?(method)
39
+ sfo_single_attr?(method) or sfo_multiple_attr?(method)
40
+ end
41
+
42
+ def sfo_single_attr?(method)
43
+ method.to_s[sfo_single_attr_regexp] ? true : false
44
+ end
45
+
46
+ def sfo_multiple_attr?(string)
47
+ string.to_s[sfo_multiple_attr_regexp] ? true : false
48
+ end
49
+
50
+ def sfo_date_attr?(tag_name)
51
+ tag_name.to_s[sfo_date_attr_regexp] ? true : false
52
+ end
53
+
54
+ def sfo_get_tag_name(object_name, method, multiple)
55
+ if sfo_multiple_attr?(object_name)
56
+ method.to_s[sfo_single_attr_regexp]
57
+ model_name = $1
58
+ attr_name = $2
59
+ tag_name = "#{object_name}[#{model_name}][][#{attr_name}]#{"[]" if multiple}"
60
+ elsif sfo_single_attr?(method)
61
+ method.to_s[sfo_single_attr_regexp]
62
+ model_name = $1
63
+ attr_name = $2
64
+ tag_name = "#{object_name}[#{model_name}][#{attr_name}]#{"[]" if multiple}"
65
+ end
66
+
67
+ tag_name
68
+ end
69
+
70
+ def sfo_get_method_name(method)
71
+ if sfo_single_attr?(method)
72
+ method.to_s[sfo_single_attr_regexp]
73
+ model_name = $1
74
+ attr_name = $2
75
+ method = "#{model_name}_#{attr_name}"
76
+ end
77
+
78
+ method
79
+ end
80
+
81
+ def sfo_get_date_tag_name(prefix, tag_name)
82
+ if sfo_multiple_attr?(prefix)
83
+ tag_name[sfo_date_attr_regexp]
84
+ model_name = $1
85
+ attr_name = $2
86
+ date_type = $3
87
+ tag_name = "#{prefix}[#{model_name}][][#{attr_name}#{date_type}]"
88
+ elsif tag_name[sfo_date_attr_regexp]
89
+ model_name = $1
90
+ attr_name = $2
91
+ date_type = $3
92
+ tag_name = "#{prefix}[#{model_name}][#{attr_name}#{date_type}]"
93
+ end
94
+
95
+ tag_name
96
+ end
97
+ end
98
+
99
+ class DateTimeSelector
100
+ include HelperMethods
101
+
102
+ def input_name_from_type(type)
103
+ prefix = @options[:prefix] || ActionView::Helpers::DateTimeSelector::DEFAULT_PREFIX
104
+ prefix += "[#{@options[:index]}]" if @options.has_key?(:index)
105
+
106
+ field_name = @options[:field_name] || type
107
+ if @options[:include_position]
108
+ field_name += "(#{ActionView::Helpers::DateTimeSelector::POSITION[type]}i)"
109
+ end
110
+
111
+ return sfo_get_date_tag_name(prefix, field_name) if sfo_date_attr?(field_name)
112
+
113
+ @options[:discard_type] ? prefix : "#{prefix}[#{field_name}]"
114
+
115
+ end
116
+ end
117
+
118
+ module Tags
119
+ class Base
120
+ include HelperMethods
121
+
122
+ private
123
+
124
+ def value(object)
125
+ method_name = sfo_get_method_name(@method_name)
126
+ object.public_send method_name if object
127
+ end
128
+
129
+ def tag_name(multiple = false, index = nil)
130
+ return sfo_get_tag_name(@object_name, sanitized_method_name, multiple) if sfo_attr?(sanitized_method_name)
131
+
132
+ if index
133
+ "#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]" if multiple}"
134
+ else
135
+ "#{@object_name}[#{sanitized_method_name}]#{"[]" if multiple}"
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ class FormBuilder
142
+ include HelperMethods
143
+ end
144
+
145
+ module FormHelper
146
+ include HelperMethods
147
+
148
+ def fields_for(record_name, record_object = nil, options = {}, &block)
149
+ if options[:sfo_multiple]
150
+ record_name[/^([\s\S]+)(\[[\s\S]+\])/]
151
+ part_1 = $1
152
+ part_2 = $2
153
+ record_name = "#{part_1}[sfo-multiple]#{part_2}"
154
+ end
155
+ builder = instantiate_builder(record_name, record_object, options)
156
+ capture(builder, &block)
157
+ end
158
+ end
159
+
160
+ end
161
+ end
@@ -1,5 +1,6 @@
1
1
  module HelperMethods
2
2
  def snake(string)
3
+ string = string.to_s
3
4
  string.gsub!(/((\w)([A-Z]))/,'\2_\3')
4
5
  class_name_if_module(string.downcase)
5
6
  end
@@ -8,4 +9,12 @@ module HelperMethods
8
9
  return $1 if string =~ /^.+::(.+)$/
9
10
  string
10
11
  end
12
+
13
+ def get_self_object(model)
14
+ method( snake(model.to_s).to_sym ).call
15
+ end
16
+
17
+ def get_class_of_snake_model_name(snake_model_name)
18
+ Object.const_get( snake_model_name.to_s.split('_').map(&:capitalize).join )
19
+ end
11
20
  end
@@ -1,163 +1,117 @@
1
+ require 'byebug'
2
+
1
3
  module SlimFormObject
4
+ class Base
5
+ include ActiveModel::Model
6
+ include ::HelperMethods
7
+ extend ::HelperMethods
2
8
 
3
- def self.included(base)
4
- base.include ActiveModel::Model
5
- base.include HelperMethods
6
- base.extend ClassMethods
7
- base.extend HelperMethods
8
- end
9
+ attr_accessor :params, :array_objects_for_save, :hash_objects_for_save
9
10
 
10
- module ClassMethods
11
+ class << self
11
12
 
12
- def init_models(*args)
13
- self.instance_eval do
14
- define_method(:array_of_models) { args }
13
+ def set_model_name(name)
14
+ define_method(:model_name) { ActiveModel::Name.new(self, nil, name) }
15
15
  end
16
- add_attributes(args)
17
- end
18
16
 
19
- def add_attributes(models)
20
- #attr_accessor for models and env params
21
- attr_accessor :params
22
- models.each{ |model| attr_accessor snake(model.to_s).to_sym }
23
-
24
- #delegate attributes of models
25
- models.each do |model|
26
- model.column_names.each do |attr|
27
- delegate attr.to_sym, "#{attr}=".to_sym,
28
- to: snake(model.to_s).to_sym,
29
- prefix: snake(model.to_s).to_sym
17
+ def init_single_models(*args)
18
+ define_array_of_models(:array_of_all_models, args)
19
+ end
20
+ alias_method :init_models, :init_single_models
21
+
22
+ def not_save_this_model(*args)
23
+ self.instance_eval do
24
+ define_method(:not_validate_this_models) { args }
30
25
  end
31
26
  end
32
- end
33
27
 
34
- def set_model_name(name)
35
- define_method(:model_name) { ActiveModel::Name.new(self, nil, name) }
36
- end
37
- end
28
+ def force_save_if_all_attr_is_nil(*args)
29
+ self.instance_eval do
30
+ define_method(:force_save_if_all_attr_is_nil) { args }
31
+ end
32
+ end
38
33
 
39
- def submit
40
- @array_of_models ||= array_of_models.reject do |model|
41
- array_of_models_without_validates.include?(model) if self.respond_to?(:array_of_models_without_validates)
42
- end
43
- update_attributes
44
- update_attributes_for_collection
45
- self
46
- end
34
+ def define_array_of_models(name, args)
35
+ self.instance_eval do
36
+ define_method(name) { args }
37
+ end
38
+ make_methods_for_objects_of(args)
39
+ end
47
40
 
48
- alias_method :apply_parameters, :submit
41
+ def make_methods_for_objects_of(models)
42
+ models.each{ |model| attr_accessor snake(model.to_s).to_sym }
43
+
44
+ delegate_models_attributes(models)
45
+ end
49
46
 
50
- def save
51
- if valid?
52
- models = Array.new(@array_of_models)
53
- while model1 = models.delete( models[0] )
54
- models.each{ |model2| save_models(model1, model2) }
47
+ def delegate_models_attributes(models)
48
+ models.each do |model|
49
+ model.column_names.each do |attr|
50
+ delegate attr.to_sym, "#{attr}=".to_sym, to: snake(model.to_s).to_sym, prefix: true
51
+ end
52
+ end
55
53
  end
56
- return true
57
54
  end
58
- false
59
- end
60
55
 
61
- def not_validate(*args)
62
- define_singleton_method(:array_of_models_without_validates) { args }
63
- end
56
+ def initialize(params: {})
57
+ self.params = params
58
+ get_or_add_default_objects
59
+ end
60
+
61
+ def get_or_add_default_objects
62
+ array_of_all_models.map do |model|
63
+ if get_self_object(model) == nil
64
+ method( "#{snake(model.to_s)}=" ).call(model.new)
65
+ else
66
+ get_self_object(model)
67
+ end
68
+ end
69
+ end
70
+ # INIT END
64
71
 
65
- private
66
72
 
67
- def save_models(model1, model2)
68
- self_object_of_model1 = method( snake(model1.to_s) ).call
69
- self_object_of_model2 = method( snake(model2.to_s) ).call
70
- association = get_association(model1, model2)
73
+ def apply_parameters
74
+ check_array_settings_with_settings
75
+ apply
76
+ end
77
+ alias_method :submit, :apply_parameters
71
78
 
72
- if association == :belongs_to or association == :has_one
73
- self_object_of_model1.send( "#{snake(model2.to_s)}=", self_object_of_model2 )
74
- self_object_of_model1.save!
75
- elsif association == :has_many or association == :has_and_belongs_to_many
76
- self_object_of_model1.method("#{model2.table_name}").call << self_object_of_model2
77
- self_object_of_model1.save!
79
+ def save
80
+ Saver.new(self).save
78
81
  end
79
- end
80
82
 
81
- def validation_models
82
- @array_of_models.each do |model|
83
- set_errors( method(snake(model.to_s)).call.errors ) unless method( snake(model.to_s) ).call.valid?
83
+ def validation_models
84
+ Validator.new(self).validate_form_object
84
85
  end
85
- end
86
86
 
87
- def set_errors(model_errors)
88
- model_errors.each do |attribute, message|
89
- errors.add(attribute, message)
87
+ # POMOGAY
88
+
89
+ def apply
90
+ assign = Assign.new(self)
91
+ @hash_objects_for_save = assign.apply_parameters
92
+ end
93
+
94
+ def check_array_settings_with_settings
95
+ define_singleton_method(:not_save_this_model) { [] } unless respond_to?(:not_validate_this_model)
96
+ define_singleton_method(:force_save_if_all_attr_is_nil) { [] } unless respond_to?(:force_save_if_all_attr_is_nil)
90
97
  end
91
- end
92
98
 
93
- def update_attributes
94
- @array_of_models.each do |model|
95
- model_attributes = make_attributes_of_model(model)
96
- method( snake(model.to_s) ).call.assign_attributes( get_attributes_for_update(model_attributes, model) )
99
+ def set_errors(object_errors)
100
+ object_errors.each do |attribute, message|
101
+ errors.add(attribute, message)
102
+ end
97
103
  end
98
- end
99
104
 
100
- def update_attributes_for_collection
101
- @array_of_models.each do |model|
102
- assign_attributes_for_collection(model)
105
+ def array_all_objects_for_save
106
+ array_objects_for_save ||= get_or_add_default_objects
103
107
  end
104
- end
105
108
 
106
- def keys_of_collections
107
- @keys ||= []
108
- params.keys.each do |key|
109
- @array_of_models.each do |model|
110
- self_object_of_model = method( snake(model.to_s) ).call
111
- method_name = key.to_s[/#{snake(model.to_s)}_(.*)/, 1]
112
- @keys << method_name if self_object_of_model.respond_to? method_name.to_s
113
- end if key[/^.+_ids$/]
114
- end if @keys.empty?
115
- @keys
116
109
  end
110
+ end
117
111
 
118
- def exist_any_errors_without_collections?
119
- keys_of_collections.each do |method_name|
120
- @array_of_models.each do |model|
121
- name_of_model = method_name.to_s[/^(.+)_ids$/, 1]
122
- name_of_constant_model = name_of_model.split('_').map(&:capitalize).join
123
- name_of_key_error = Object.const_get(name_of_constant_model).table_name
124
- errors.messages.delete(name_of_key_error.to_sym)
125
- end
126
- end unless valid?
127
- errors.messages.empty?
128
- end
129
112
 
130
- def assign_attributes_for_collection(model)
131
- self_object_of_model = method( snake(model.to_s) ).call
132
113
 
133
- keys_of_collections.each do |method_name|
134
- if self_object_of_model.respond_to? method_name
135
- old_attribute = self_object_of_model.method( method_name ).call
136
- unless self_object_of_model.update_attributes( {method_name.to_s => params["#{snake(model.to_s)}_#{method_name}".to_sym]} )
137
- set_errors(self_object_of_model.errors)
138
- self_object_of_model.update_attributes( {method_name.to_s => old_attribute} )
139
- end if exist_any_errors_without_collections?
140
- end
141
- end
142
- end
143
114
 
144
- def make_attributes_of_model(model)
145
- model_attributes = []
146
- model.column_names.each do |name|
147
- model_attributes << "#{snake(model.to_s)}_#{name}"
148
- end
149
- model_attributes
150
- end
151
115
 
152
- def get_attributes_for_update(model_attributes, model)
153
- update_attributes = {}
154
- hash_attributes = params.slice(*model_attributes)
155
- hash_attributes.each{ |attr, val| update_attributes[attr.gsub(/#{snake(model.to_s)}_(.*)/, '\1')] = val }
156
- update_attributes
157
- end
158
116
 
159
- def get_association(class1, class2)
160
- class1.reflections.slice(snake(class2.to_s), class2.table_name).values.first&.macro
161
- end
162
117
 
163
- end
@@ -0,0 +1,81 @@
1
+ module SlimFormObject
2
+ class Saver
3
+ include ::HelperMethods
4
+
5
+ attr_reader :form_object, :params, :validator, :hash_objects_for_save
6
+
7
+ def initialize(form_object)
8
+ @form_object = form_object
9
+ @params = form_object.params
10
+ @hash_objects_for_save = form_object.hash_objects_for_save
11
+ @validator = Validator.new(form_object)
12
+ end
13
+
14
+ def save
15
+ if form_object.valid?
16
+ ActiveRecord::Base.transaction do
17
+ save_main_objects
18
+ save_nested_objects
19
+ end
20
+ return true
21
+ end
22
+ false
23
+ rescue
24
+ # p "ERROR"
25
+ false
26
+ end
27
+
28
+ def save_main_objects
29
+ objects = Array.new(hash_objects_for_save[:objects])
30
+ while object_1 = objects.delete( objects[0] )
31
+ objects.each{ |object_2| save_objects(object_1, object_2) }
32
+ save_last_model_if_not_associations(object_1)
33
+ end
34
+ end
35
+
36
+ def save_nested_objects
37
+ hash_objects_for_save[:objects].each do |object_1|
38
+ next unless hash_objects_for_save[:nested_objects].include?( snake(object_1.class).to_sym )
39
+ hash_objects_for_save[:nested_objects][snake(object_1.class).to_sym].each do |object_2|
40
+ save_objects(object_1, object_2)
41
+ end
42
+ end
43
+ end
44
+
45
+ def save_objects(object_1, object_2)
46
+ object_for_save = to_bind_models(object_1, object_2)
47
+ save_object(object_for_save)
48
+ end
49
+
50
+ def to_bind_models(object_1, object_2)
51
+ association = get_association(object_1.class, object_2.class)
52
+
53
+ if association == :belongs_to or association == :has_one
54
+ object_1.send( "#{snake(object_2.class.to_s)}=", object_2 )
55
+ elsif association == :has_many or association == :has_and_belongs_to_many
56
+ object_1.method("#{object_2.class.table_name}").call << object_2
57
+ end
58
+
59
+ object_1
60
+ end
61
+
62
+ def save_object(object_of_model)
63
+ if validator.valid_model_for_save?(object_of_model.class)
64
+ object_of_model.save!
65
+ end
66
+ end
67
+
68
+ def save_last_model_if_not_associations(object_1)
69
+ association_trigger = false
70
+ hash_objects_for_save[:objects].each { |object_2| association_trigger = true if get_association(object_1.class, object_2.class) }
71
+ object_1.save unless association_trigger
72
+ rescue
73
+ object_1.class.find(object_1.id).update!(object_1.attributes)
74
+ end
75
+
76
+ def get_association(class1, class2)
77
+ class1.reflections.slice(snake(class2.to_s), class2.table_name).values.first&.macro
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,297 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ # require 'byebug'
10
+
11
+ # module SlimFormObject
12
+ # class Base
13
+ # attr_accessor :params
14
+
15
+ # def self.init_models(*args)
16
+ # self.instance_eval do
17
+ # define_method(:array_of_single_models) { args }
18
+ # end
19
+ # add_attributes(args)
20
+ # end
21
+
22
+ # alias_method :init_single_models, :init_models
23
+
24
+ # def self.init_multiple_models(*args)
25
+ # self.instance_eval do
26
+ # define_method(:array_multiple_models) { args }
27
+ # end
28
+ # add_attributes(args)
29
+ # end
30
+
31
+ # def self.add_attributes(models)
32
+ # #acessors for model objects
33
+ # models.each{ |model| attr_accessor snake(model.to_s).to_sym }
34
+
35
+ # #delegate attributes of models
36
+ # models.each do |model|
37
+ # model.column_names.each do |attr|
38
+ # delegate attr.to_sym, "#{attr}=".to_sym, to: snake(model.to_s).to_sym,
39
+ # prefix: true
40
+ # end
41
+ # end
42
+ # end
43
+
44
+ # def self.set_model_name(name)
45
+ # define_method(:model_name) { ActiveModel::Name.new(self, nil, name) }
46
+ # end
47
+ # # def initializer
48
+
49
+ # # end
50
+ # end
51
+
52
+ # def self.included(base)
53
+ # # define_properties(base)
54
+
55
+ # base.include ActiveModel::Model
56
+ # base.include HelperMethods
57
+ # base.extend ClassMethods
58
+ # base.extend HelperMethods
59
+ # end
60
+
61
+ # # def self.define_properties(form_object_klass)
62
+ # # class << form_object_klass
63
+ # # #attr_accessor for models and env params
64
+ # # # attr_accessor :params
65
+
66
+ # # # byebug
67
+
68
+ # # # def params=(val)
69
+ # # # @params = val
70
+ # # # end
71
+
72
+ # # # def params
73
+ # # # @params
74
+ # # # end
75
+ # # end
76
+ # # end
77
+
78
+ # # module ClassMethods
79
+
80
+ # # def init_models(*args)
81
+ # # self.instance_eval do
82
+ # # define_method(:array_of_single_models) { args }
83
+ # # end
84
+ # # add_attributes(args)
85
+ # # end
86
+
87
+ # # alias_method :init_single_models, :init_models
88
+
89
+ # # def init_multiple_models(*args)
90
+ # # self.instance_eval do
91
+ # # define_method(:array_multiple_models) { args }
92
+ # # end
93
+ # # add_attributes(args)
94
+ # # end
95
+
96
+ # # def add_attributes(models)
97
+ # # #acessors for model objects
98
+ # # models.each{ |model| attr_accessor snake(model.to_s).to_sym }
99
+
100
+ # # #delegate attributes of models
101
+ # # models.each do |model|
102
+ # # model.column_names.each do |attr|
103
+ # # delegate attr.to_sym, "#{attr}=".to_sym, to: snake(model.to_s).to_sym,
104
+ # # prefix: true
105
+ # # end
106
+ # # end
107
+ # # end
108
+
109
+ # # def set_model_name(name)
110
+ # # define_method(:model_name) { ActiveModel::Name.new(self, nil, name) }
111
+ # # end
112
+ # # end
113
+
114
+ # def submit
115
+ # @array_of_single_models ||= array_of_single_models.reject do |model|
116
+ # array_of_single_models_without_validates.include?(model) if self.respond_to?(:array_of_single_models_without_validates)
117
+ # end
118
+ # update_attributes
119
+ # update_attributes_for_collection
120
+ # self
121
+ # end
122
+
123
+ # alias_method :apply_parameters, :submit
124
+
125
+ # def save
126
+ # if valid?
127
+ # models = Array.new(@array_of_single_models)
128
+ # while model1 = models.delete( models[0] )
129
+ # models.each{ |model2| save_models(model1, model2) }
130
+ # save_last_model_if_not_associations(model1) if models.empty?
131
+ # end
132
+ # return true
133
+ # end
134
+ # false
135
+ # end
136
+
137
+ # def not_validate(*args)
138
+ # define_singleton_method(:array_of_single_models_without_validates) { args }
139
+ # end
140
+
141
+ # private
142
+
143
+ # def save_models(model_1, model_2)
144
+ # self_object_of_model_for_save = nil
145
+ # byebug
146
+ # if both_model_attributes_exist?(model_1, model_2)
147
+ # # byebug
148
+ # self_object_of_model_for_save = to_bind_models(model_1, model_2)
149
+ # save_model(self_object_of_model_for_save)
150
+ # else
151
+ # get_self_objects_of_model(model_1, model_2).each do |object|
152
+ # save_model(object)
153
+ # end
154
+ # end
155
+ # end
156
+
157
+ # def to_bind_models(model_1, model_2)
158
+ # self_object_of_model_1, self_object_of_model_2 = get_self_objects_of_model(model_1, model_2)
159
+ # association = get_association(model_1, model_2)
160
+
161
+ # if association == :belongs_to or association == :has_one
162
+ # self_object_of_model_1.send( "#{snake(model_2.to_s)}=", self_object_of_model_2 )
163
+ # elsif association == :has_many or association == :has_and_belongs_to_many
164
+ # self_object_of_model_1.method("#{model_2.table_name}").call << self_object_of_model_2
165
+ # end
166
+
167
+ # self_object_of_model_1
168
+ # end
169
+
170
+ # def valid_model_for_save?(model)
171
+ # ( (attributes_is_present?(model) and method( snake(model.to_s) ).call.id != nil) or (method( snake(model.to_s) ).call.id == nil and !all_attributes_is_empty?(model)) )
172
+ # end
173
+
174
+ # def attributes_is_present?(model)
175
+ # (make_attributes_of_model(model) & params.keys).present?
176
+ # end
177
+
178
+ # def both_model_attributes_exist?(model_1, model_2)
179
+ # valid_model_for_save?(model_1) and valid_model_for_save?(model_2)
180
+ # end
181
+
182
+ # def save_model(self_object_of_model)
183
+ # if valid_model_for_save?(self_object_of_model.class)
184
+ # self_object_of_model.save!
185
+ # end
186
+ # end
187
+
188
+ # def all_attributes_is_empty?(model)
189
+ # is_empty = true
190
+ # array_symbols_of_attributes = (make_attributes_of_model(model) & params.keys).map { |attr| attr.to_sym }
191
+ # params.slice(*array_symbols_of_attributes).values.each do |value|
192
+ # is_empty = false unless value == ""
193
+ # end
194
+ # is_empty
195
+ # end
196
+
197
+ # def get_self_objects_of_model(model_1, model_2)
198
+ # [ method( snake(model_1.to_s) ).call, method( snake(model_2.to_s) ).call ]
199
+ # end
200
+
201
+ # def save_last_model_if_not_associations(model)
202
+ # association_trigger = false
203
+ # self_object_of_model = method( snake(model.to_s) ).call
204
+ # @array_of_single_models.each { |model2| association_trigger = true if get_association(model, model2) }
205
+ # self_object_of_model.save unless association_trigger
206
+ # rescue
207
+ # self_object_of_model.class.find(self_object_of_model.id).update!(self_object_of_model.attributes)
208
+ # end
209
+
210
+ # def validation_models
211
+ # @array_of_single_models.each do |model|
212
+ # next unless valid_model_for_save?(model)
213
+ # set_errors( method(snake(model.to_s)).call.errors ) unless method( snake(model.to_s) ).call.valid?
214
+ # end
215
+ # end
216
+
217
+ # def set_errors(model_errors)
218
+ # model_errors.each do |attribute, message|
219
+ # errors.add(attribute, message)
220
+ # end
221
+ # end
222
+
223
+ # def update_attributes
224
+ # @array_of_single_models.each do |model|
225
+ # model_attributes = make_attributes_of_model(model)
226
+ # method( snake(model.to_s) ).call.assign_attributes( get_attributes_for_update(model_attributes, model) )
227
+ # end
228
+ # end
229
+
230
+ # def update_attributes_for_collection
231
+ # @array_of_single_models.each do |model|
232
+ # assign_attributes_for_collection(model)
233
+ # end
234
+ # end
235
+
236
+ # def keys_of_collections
237
+ # @keys ||= []
238
+ # params.keys.each do |key|
239
+ # @array_of_single_models.each do |model|
240
+ # self_object_of_model = method( snake(model.to_s) ).call
241
+ # method_name = key.to_s[/#{snake(model.to_s)}_(.*)/, 1]
242
+ # @keys << method_name if self_object_of_model.respond_to? method_name.to_s
243
+ # end if key[/^.+_ids$/]
244
+ # end if @keys.empty?
245
+ # @keys
246
+ # end
247
+
248
+ # def exist_any_errors_without_collections?
249
+ # keys_of_collections.each do |method_name|
250
+ # @array_of_single_models.each do |model|
251
+ # name_of_model = method_name.to_s[/^(.+)_ids$/, 1]
252
+ # name_of_constant_model = name_of_model.split('_').map(&:capitalize).join
253
+ # name_of_key_error = Object.const_get(name_of_constant_model).table_name
254
+ # errors.messages.delete(name_of_key_error.to_sym)
255
+ # end
256
+ # end unless valid?
257
+ # errors.messages.empty?
258
+ # end
259
+
260
+ # def assign_attributes_for_collection(model)
261
+ # self_object_of_model = method( snake(model.to_s) ).call
262
+
263
+ # keys_of_collections.each do |method_name|
264
+ # if self_object_of_model.respond_to? method_name
265
+ # old_attribute = self_object_of_model.method( method_name ).call
266
+ # unless self_object_of_model.update_attributes( {method_name.to_s => params["#{snake(model.to_s)}_#{method_name}".to_sym]} )
267
+ # set_errors(self_object_of_model.errors)
268
+ # self_object_of_model.update_attributes( {method_name.to_s => old_attribute} )
269
+ # end if exist_any_errors_without_collections?
270
+ # end
271
+ # end
272
+ # end
273
+
274
+ # def make_attributes_of_model(model)
275
+ # model_attributes = []
276
+ # model.column_names.each do |name|
277
+ # model_attributes << "#{snake(model.to_s)}_#{name}"
278
+ # end
279
+ # model_attributes
280
+ # end
281
+
282
+ # def get_attributes_for_update(model_attributes, model)
283
+ # attributes_for_update = {}
284
+ # hash_attributes = params.slice(*model_attributes)
285
+ # hash_attributes.each{ |attr, val| attributes_for_update[attr.gsub(/#{snake(model.to_s)}_(.*)/, '\1')] = val }
286
+ # attributes_for_update
287
+ # end
288
+
289
+ # def get_association(class1, class2)
290
+ # class1.reflections.slice(snake(class2.to_s), class2.table_name).values.first&.macro
291
+ # end
292
+
293
+
294
+ # # get attributes
295
+ # # .gsub(/^\[|\]$|"/, '').split(', ')
296
+
297
+ # end
@@ -0,0 +1,55 @@
1
+ module SlimFormObject
2
+ class Validator
3
+ include ::HelperMethods
4
+
5
+ attr_reader :form_object, :params, :hash_objects_for_save
6
+
7
+ def initialize(form_object)
8
+ @form_object = form_object
9
+ @params = form_object.params
10
+ @hash_objects_for_save = form_object.hash_objects_for_save
11
+ end
12
+
13
+ def validate_form_object
14
+ filter_nil_objects
15
+
16
+ hash_objects_for_save[:objects].each do |object|
17
+ next if all_attributes_is_nil?(object)
18
+ form_object.set_errors( object.errors ) unless object.valid?
19
+ end
20
+
21
+ hash_objects_for_save[:nested_objects].keys.each do |snake_model_name|
22
+ hash_objects_for_save[:nested_objects][snake_model_name].each do |object|
23
+ form_object.set_errors( object.errors ) unless object.valid?
24
+ end
25
+ end
26
+ end
27
+
28
+ def filter_nil_objects
29
+ hash_objects_for_save[:objects].reject! do |object|
30
+ all_attributes_is_nil?(object)
31
+ end
32
+ end
33
+
34
+ def valid_model_for_save?(object)
35
+ # ( (attributes_is_present?(object) and object.id != nil) or (object.id == nil and !all_attributes_is_empty?(object)) )
36
+ true
37
+ end
38
+
39
+ def both_model_attributes_exist?(object_1, object_2)
40
+ # valid_model_for_save?(object_1) and valid_model_for_save?(object_2)
41
+ !(all_attributes_is_nil?(object_1) and all_attributes_is_nil?(object_2))
42
+ end
43
+
44
+ def all_attributes_is_nil?(object)
45
+ object.class.column_names.each do |attr_name|
46
+ return false if object.send(attr_name.to_sym) != nil
47
+ end
48
+ true
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+
55
+
@@ -1,3 +1,3 @@
1
1
  module SlimFormObject
2
- VERSION = "0.5.23"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -1,5 +1,5 @@
1
1
 
2
- class CreateModelOne < ActiveRecord::Migration
2
+ class CreateModelOne < ActiveRecord::Migration[5.0]
3
3
  def self.up
4
4
  create_table :test_one_models do |t|
5
5
  t.string :title
@@ -1,5 +1,5 @@
1
1
 
2
- class CreateModelTwo < ActiveRecord::Migration
2
+ class CreateModelTwo < ActiveRecord::Migration[5.0]
3
3
  def self.up
4
4
  create_table :test_two_models do |t|
5
5
  t.string :title
@@ -1,5 +1,5 @@
1
1
 
2
- class CreateModelThree < ActiveRecord::Migration
2
+ class CreateModelThree < ActiveRecord::Migration[5.0]
3
3
  def self.up
4
4
  create_table :test_three_models do |t|
5
5
  t.string :title
@@ -1,5 +1,5 @@
1
1
 
2
- class CreateModelFour < ActiveRecord::Migration
2
+ class CreateModelFour < ActiveRecord::Migration[5.0]
3
3
  def self.up
4
4
  create_table :test_four_models do |t|
5
5
  t.string :title
@@ -1,5 +1,5 @@
1
1
 
2
- class CreateModelOneFour < ActiveRecord::Migration
2
+ class CreateModelOneFour < ActiveRecord::Migration[5.0]
3
3
  def self.up
4
4
  create_table :test_one_four_models do |t|
5
5
  t.integer :test_one_model_id
@@ -1,5 +1,5 @@
1
1
 
2
- class CreateModelTwoThree < ActiveRecord::Migration
2
+ class CreateModelTwoThree < ActiveRecord::Migration[5.0]
3
3
  def self.up
4
4
  create_table :test_three_model_test_two_models do |t|
5
5
  t.integer :test_three_model_id
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: 0.5.23
4
+ version: 1.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-01-23 00:00:00.000000000 Z
11
+ date: 2017-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.0.0
19
+ version: 5.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 4.0.0
26
+ version: 5.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionview
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 5.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 5.0.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -147,8 +161,13 @@ extra_rdoc_files: []
147
161
  files:
148
162
  - bin/slim_form_object
149
163
  - lib/slim_form_object.rb
164
+ - lib/slim_form_object/assign.rb
165
+ - lib/slim_form_object/form_helpers/extension_actionview.rb
150
166
  - lib/slim_form_object/helpers.rb
151
167
  - lib/slim_form_object/processing.rb
168
+ - lib/slim_form_object/saver.rb
169
+ - lib/slim_form_object/tmp.rb
170
+ - lib/slim_form_object/validator.rb
152
171
  - lib/slim_form_object/version.rb
153
172
  - spec/db/database.yml
154
173
  - spec/db/database.yml.travis