object_attorney 2.10.12 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +48 -17
  3. data/.rubocop.yml +19 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +0 -13
  7. data/Gemfile.lock +83 -0
  8. data/README.md +25 -18
  9. data/Rakefile +7 -16
  10. data/lib/object_attorney.rb +57 -44
  11. data/lib/object_attorney/accusation.rb +46 -0
  12. data/lib/object_attorney/allegation.rb +20 -0
  13. data/lib/object_attorney/base.rb +17 -0
  14. data/lib/object_attorney/class_methods.rb +50 -0
  15. data/lib/object_attorney/errors.rb +32 -0
  16. data/lib/object_attorney/helpers.rb +22 -21
  17. data/lib/object_attorney/validations/custom.rb +23 -0
  18. data/lib/object_attorney/version.rb +3 -1
  19. data/object_attorney.gemspec +24 -17
  20. data/spec/object_attorney/base_spec.rb +21 -0
  21. data/spec/object_attorney/custom_validation_spec.rb +60 -0
  22. data/spec/object_attorney/object_attorney_spec.rb +64 -0
  23. data/spec/spec_helper.rb +17 -56
  24. data/spec/support/post.rb +7 -0
  25. data/spec/support/user.rb +5 -0
  26. metadata +102 -127
  27. data/.rvmrc +0 -1
  28. data/Guardfile +0 -5
  29. data/console.rb +0 -36
  30. data/db/migrate/20131205114000_create_users.rb +0 -13
  31. data/db/migrate/20131205114900_create_posts.rb +0 -14
  32. data/db/migrate/20131205114901_create_comments.rb +0 -13
  33. data/db/migrate/20131205114902_create_addresses.rb +0 -14
  34. data/db/schema.rb +0 -22
  35. data/lib/object_attorney/association_reflection.rb +0 -72
  36. data/lib/object_attorney/attribute_assignment.rb +0 -69
  37. data/lib/object_attorney/delegation.rb +0 -48
  38. data/lib/object_attorney/naming.rb +0 -16
  39. data/lib/object_attorney/nested_objects.rb +0 -311
  40. data/lib/object_attorney/orm_handlers/smooth_operator.rb +0 -69
  41. data/lib/object_attorney/record.rb +0 -117
  42. data/lib/object_attorney/reflection.rb +0 -40
  43. data/lib/object_attorney/representation.rb +0 -93
  44. data/lib/object_attorney/serialization.rb +0 -43
  45. data/lib/object_attorney/translation.rb +0 -25
  46. data/lib/object_attorney/validations.rb +0 -46
  47. data/not_used/nested_uniqueness_validator.rb +0 -33
  48. data/spec/object_attorney/address_form_spec.rb +0 -45
  49. data/spec/object_attorney/bulk_post_form_spec.rb +0 -52
  50. data/spec/object_attorney/bulk_posts_allow_only_existing_form_spec.rb +0 -37
  51. data/spec/object_attorney/bulk_posts_allow_only_new_form_spec.rb +0 -39
  52. data/spec/object_attorney/bulk_posts_with_form_objects_form_spec.rb +0 -91
  53. data/spec/object_attorney/delegation_spec.rb +0 -142
  54. data/spec/object_attorney/nested_objects_spec.rb +0 -63
  55. data/spec/object_attorney/post_form_spec.rb +0 -154
  56. data/spec/object_attorney/post_validations_form_spec.rb +0 -46
  57. data/spec/object_attorney/post_with_comment_form_spec.rb +0 -123
  58. data/spec/object_attorney/post_with_comment_validations_form_spec.rb +0 -46
  59. data/spec/object_attorney/post_with_comments_and_address_form_spec.rb +0 -54
  60. data/spec/object_attorney/post_with_only_existing_comments_form_spec.rb +0 -38
  61. data/spec/object_attorney/post_with_only_new_comments_form_spec.rb +0 -42
  62. data/spec/object_attorney/serialization_spec.rb +0 -40
  63. data/spec/object_attorney/test_spec.rb +0 -23
  64. data/spec/object_attorney/user_and_comments_form_spec.rb +0 -56
  65. data/spec/object_attorney/user_form_spec.rb +0 -70
  66. data/spec/require_helper.rb +0 -32
  67. data/spec/support/active_model/validations.rb +0 -21
  68. data/spec/support/database_setup.rb +0 -14
  69. data/spec/support/form_objects/address_form.rb +0 -9
  70. data/spec/support/form_objects/bulk_posts_allow_only_existing_form.rb +0 -19
  71. data/spec/support/form_objects/bulk_posts_allow_only_new_form.rb +0 -19
  72. data/spec/support/form_objects/bulk_posts_form.rb +0 -27
  73. data/spec/support/form_objects/bulk_posts_with_form_objects_form.rb +0 -27
  74. data/spec/support/form_objects/comment_form.rb +0 -11
  75. data/spec/support/form_objects/post_form.rb +0 -120
  76. data/spec/support/form_objects/post_validations_form.rb +0 -17
  77. data/spec/support/form_objects/post_with_comment_form.rb +0 -21
  78. data/spec/support/form_objects/post_with_comment_validations_form.rb +0 -17
  79. data/spec/support/form_objects/post_with_comments_and_address_form.rb +0 -13
  80. data/spec/support/form_objects/post_with_only_existing_comments_form.rb +0 -9
  81. data/spec/support/form_objects/post_with_only_new_comments_form.rb +0 -9
  82. data/spec/support/form_objects/user_and_comments_form.rb +0 -11
  83. data/spec/support/form_objects/user_form.rb +0 -11
  84. data/spec/support/models/address.rb +0 -5
  85. data/spec/support/models/comment.rb +0 -5
  86. data/spec/support/models/post.rb +0 -9
  87. data/spec/support/models/user.rb +0 -7
@@ -1,69 +0,0 @@
1
- module ObjectAttorney
2
- module OrmHandlers
3
-
4
- module SmoothOperator
5
-
6
- def save(options = {})
7
- save_or_! { submit(options) }
8
- end
9
-
10
- def save!(options = {})
11
- save_or_! { submit!(options) }
12
- end
13
-
14
- def submit(options = {})
15
- submit_or_!(:save, options)
16
- end
17
-
18
- def submit!(options = {})
19
- submit_or_!(:save!, options)
20
- end
21
-
22
- def destroy(options = {})
23
- return true if represented_object.blank?
24
- represented_object.destroy(options).ok?
25
- end
26
-
27
- def call_save_or_destroy(object, save_method, options = {})
28
- if object == self || object == represented_object
29
- represented_object.present? ? represented_object.send(save_method, options).ok? : true
30
- else
31
- save_method = :destroy if Helpers.marked_for_destruction?(object)
32
- object.send(save_method, options).ok?
33
- end
34
- end
35
-
36
- protected #################### PROTECTED METHODS DOWN BELOW ######################
37
-
38
- def submit_or_!(save_method, options = {})
39
- save_result = save_or_destroy_nested_objects(save_method, :belongs_to, options)
40
- save_result = save_or_destroy_represented_object(save_method, options) if save_result
41
- save_result = save_or_destroy_nested_objects(save_method, :has_many, options) if save_result
42
- save_result = save_or_destroy_nested_objects(save_method, :has_one, options) if save_result
43
- save_result
44
- end
45
-
46
- def save_or_destroy_represented_object(save_method, options = {})
47
- return true if represented_object.blank?
48
- call_save_or_destroy(represented_object, save_method, options)
49
- end
50
-
51
- def save_or_destroy_nested_objects(save_method, association_macro, options = {})
52
- nested_objects(association_macro).map do |reflection, nested_object|
53
-
54
- populate_foreign_key(self, nested_object, reflection, :has_many)
55
- populate_foreign_key(self, nested_object, reflection, :has_one)
56
-
57
- saving_result = call_save_or_destroy(nested_object, save_method, options)
58
-
59
- populate_foreign_key(nested_object, self, reflection, :belongs_to)
60
-
61
- saving_result
62
-
63
- end.all?
64
- end
65
-
66
- end
67
-
68
- end
69
- end
@@ -1,117 +0,0 @@
1
- module ObjectAttorney
2
-
3
- module Record
4
-
5
- def id
6
- represented_object.try(:id)
7
- end
8
-
9
- def new_record?
10
- Helpers.try_or_return(represented_object, :new_record?, true)
11
- end
12
-
13
- def persisted?
14
- Helpers.try_or_return(represented_object, :persisted?, false)
15
- end
16
-
17
- def save
18
- save_or_! { submit }
19
- end
20
-
21
- def save!(save_method = :save!)
22
- save_or_! { submit! }
23
- end
24
-
25
- def submit
26
- submit_or_!(:save)
27
- end
28
-
29
- def submit!
30
- submit_or_!(:save!)
31
- end
32
-
33
- def destroy
34
- return true if represented_object.blank?
35
- represented_object.destroy
36
- end
37
-
38
- def call_save_or_destroy(object, save_method)
39
- if object == self
40
- represented_object.present? ? represented_object.send(save_method) : true
41
- else
42
- save_method = :destroy if Helpers.marked_for_destruction?(object)
43
- object.send(save_method)
44
- end
45
- end
46
-
47
- def clear_nested_imposed_errors
48
- nested_objects.each do |reflection, nested_object|
49
- nested_object.clear_imposed_errors
50
-
51
- nested_object.clear_nested_imposed_errors if nested_object.respond_to?(:clear_nested_imposed_errors)
52
- end
53
- end
54
-
55
- def populate_nested_imposed_errors
56
- nested_objects.each do |reflection, nested_object|
57
- next if Helpers.marked_for_destruction?(nested_object)
58
-
59
- nested_object.populate_imposed_errors
60
-
61
- nested_object.populate_nested_imposed_errors if nested_object.respond_to?(:populate_nested_imposed_errors)
62
- end
63
- end
64
-
65
- protected #################### PROTECTED METHODS DOWN BELOW ######################
66
-
67
- def save_or_!
68
- clear_imposed_errors
69
- clear_nested_imposed_errors
70
-
71
- before_save
72
-
73
- save_result = valid? ? yield : false
74
-
75
- populate_imposed_errors
76
- populate_nested_imposed_errors
77
-
78
- after_save if valid? && save_result
79
-
80
- save_result
81
- end
82
-
83
- def before_save; end
84
- def after_save; end
85
-
86
- def submit_or_!(save_method)
87
- save_result = save_or_destroy_nested_objects(save_method, :belongs_to)
88
- save_result = save_or_destroy_represented_object(save_method)
89
- save_result = save_or_destroy_nested_objects(save_method, :has_many) if save_result
90
- save_result = save_or_destroy_nested_objects(save_method, :has_one) if save_result
91
- save_result
92
- end
93
-
94
- def save_or_destroy_represented_object(save_method)
95
- return true if represented_object.blank?
96
- call_save_or_destroy(represented_object, save_method)
97
- end
98
-
99
- def self.included(base)
100
- base.extend(ClassMethods)
101
- end
102
-
103
- module ClassMethods
104
-
105
- def all(*args)
106
- if represented_object_class.respond_to?(:all)
107
- represented_object_class.all(*args).map { |represented_object| self.new({}, represented_object) }
108
- else
109
- []
110
- end
111
- end
112
-
113
- end
114
-
115
- end
116
-
117
- end
@@ -1,40 +0,0 @@
1
- module ObjectAttorney
2
-
3
- class Reflection
4
- attr_reader :name, :klass, :options
5
-
6
- def initialize(class_name, options)
7
- options = options.is_a?(Hash) ? options : {}
8
-
9
- @name, @options = class_name, options
10
-
11
- @klass = options[:class_name] || klass_default(@name)
12
-
13
- if options.include?(:class_name) && options[:class_name].nil?
14
- @klass = nil
15
- elsif @klass.is_a?(String)
16
- @klass = @klass.constantize
17
- end
18
- end
19
-
20
- def single_name
21
- @single_name ||= options[:single_name] || Helpers.singularize(name)
22
- end
23
-
24
- def plural_name
25
- @plural_name ||= options[:plural_name] || name.to_s.pluralize
26
- end
27
-
28
- private ################################# private
29
-
30
- def klass_default(class_name)
31
- if Helpers.plural?(class_name)
32
- class_name.to_s.singularize.camelize
33
- else
34
- class_name.to_s.camelize
35
- end
36
- end
37
-
38
- end
39
-
40
- end
@@ -1,93 +0,0 @@
1
- module ObjectAttorney
2
-
3
- module Representation
4
-
5
- def read_attribute_for_serialization(attribute)
6
- respond_to?(attribute) ? send(attribute) : nil
7
- end
8
-
9
- def send_to_representative(method_name, *args)
10
- return false if represented_object.blank?
11
-
12
- represented_object.send(method_name, *args)
13
- end
14
-
15
- def represented_object
16
- @represented_object ||= self.class.represented_object_class.try(:new)
17
- end
18
-
19
- protected #################### PROTECTED METHODS DOWN BELOW ######################
20
-
21
- def validate_represented_object
22
- represented_object_valid = Helpers.try_or_return(represented_object, :valid?, true)
23
-
24
- load_errors_from represented_object.errors unless represented_object_valid
25
-
26
- nested_valid = add_errors_entry_if_nested_invalid
27
-
28
- represented_object_valid && nested_valid
29
- end
30
-
31
- private #################### PRIVATE METHODS DOWN BELOW ######################
32
-
33
- def add_errors_entry_if_nested_invalid
34
- nested_vs_invalid = {}
35
-
36
- nested_objects.each do |reflection, nested_object|
37
- if Helpers.has_errors_method?(nested_object) && !nested_object.errors.empty? && !nested_vs_invalid.include?(reflection.name)
38
- message = errors.send(:normalize_message, reflection.name, :invalid, {})
39
-
40
- if !errors.messages[reflection.name].try(:include?, message)
41
- nested_vs_invalid[reflection.name] = message
42
- end
43
- end
44
- end
45
-
46
- load_errors_from nested_vs_invalid
47
-
48
- nested_vs_invalid.empty?
49
- end
50
-
51
- def self.included(base)
52
- base.extend(ClassMethods)
53
- end
54
-
55
- module ClassMethods
56
-
57
- def table_name
58
- self.instance_variable_get("@table_name") || represented_object_class.try(:table_name)
59
- end
60
-
61
- attr_writer :table_name
62
-
63
- def represents(represented_object_name, options = {})
64
- self.instance_variable_set("@represented_object_reflection", Reflection.new(represented_object_name, options))
65
-
66
- define_method(represented_object_name) { represented_object }
67
-
68
- properties(*options[:properties]) if options.include?(:properties)
69
- getters(*options[:getters]) if options.include?(:getters)
70
- setters(*options[:setters]) if options.include?(:setters)
71
-
72
- class_eval { include Delegation::MissingMethods } if options[:delegate_missing_methods]
73
- end
74
-
75
- def represented_object_reflection
76
- self.instance_variable_get("@represented_object_reflection") || zuper_method('represented_object_reflection')
77
- end
78
-
79
- def represented_object_class
80
- represented_object_reflection.try(:klass)
81
- end
82
-
83
- def represented_object_reflect_on_association(association)
84
- return nil if represented_object_class.nil? || !represented_object_class.respond_to?(:reflect_on_association)
85
-
86
- represented_object_class.reflect_on_association(association)
87
- end
88
-
89
- end
90
-
91
- end
92
-
93
- end
@@ -1,43 +0,0 @@
1
- module ObjectAttorney
2
-
3
- module Serialization
4
-
5
- def attributes
6
- self.class.attributes_keys.reduce({}) do |data, getter|
7
- data[getter.to_s] = send(getter)
8
- data
9
- end
10
- end
11
-
12
- def to_hash(options = {})
13
- serializable_hash(options)
14
- end
15
-
16
- def to_json(options = {})
17
- serializable_hash(options).to_json
18
- end
19
-
20
- def self.included(base)
21
- base.class_eval { include ActiveModel::Serialization }
22
- base.extend(ClassMethods)
23
- end
24
-
25
- module ClassMethods
26
-
27
- def attributes_keys
28
- return @attributes_keys if defined?(@attributes_keys)
29
-
30
- @attributes_keys = zuper_method(:attributes_keys)
31
-
32
- @attributes_keys ||= represented_object_class.present? && represented_object_class.method_defined?(:id) ? [:id] : []
33
- end
34
-
35
- def add_attribute_key(*getters)
36
- attributes_keys.push(*getters) unless attributes_keys.include?(getters)
37
- end
38
-
39
- end
40
-
41
- end
42
-
43
- end
@@ -1,25 +0,0 @@
1
- module ObjectAttorney
2
-
3
- module Translation
4
-
5
- def human_attribute_name(attribute_key_name, options = {})
6
- no_translation = "-- no translation --"
7
-
8
- defaults = ["object_attorney.attributes.#{represented_object_class.to_s.underscore}.#{attribute_key_name}".to_sym]
9
- defaults << options[:default] if options[:default]
10
- defaults.flatten!
11
- defaults << no_translation
12
- options[:count] ||= 1
13
-
14
- translation = I18n.translate(defaults.shift, options.merge(default: defaults))
15
-
16
- if translation == no_translation && represented_object_class.respond_to?(:human_attribute_name)
17
- translation = represented_object_class.human_attribute_name(attribute_key_name, options)
18
- end
19
-
20
- translation
21
- end
22
-
23
- end
24
-
25
- end
@@ -1,46 +0,0 @@
1
- module ObjectAttorney
2
- module Validations
3
-
4
- def valid?(context = nil)
5
- return true if override_validations? || !Helpers.has_errors_method?(self)
6
-
7
- context ||= (new_record? ? :create : :update)
8
- output = super(context)
9
-
10
- load_errors_from imposed_errors
11
-
12
- errors.empty? && output
13
- end
14
-
15
- def override_validations?
16
- Helpers.marked_for_destruction?(self)
17
- end
18
-
19
- def clear_imposed_errors
20
- @imposed_errors = {}
21
- end
22
-
23
- def populate_imposed_errors
24
- if respond_to?(:represented_object)
25
- represented_object.errors.each { |key, value| imposed_errors[key] = value } if Helpers.has_errors_method?(represented_object)
26
- else
27
- errors.each { |key, value| imposed_errors[key] = value } if Helpers.has_errors_method?(self)
28
- end
29
- end
30
-
31
- def imposed_errors
32
- @imposed_errors ||= {}
33
- end
34
-
35
- private #################### PRIVATE METHODS DOWN BELOW ######################
36
-
37
- def load_errors_from(errors)
38
- errors.each do |key, value|
39
- [*value].each do |_value|
40
- self.errors.add(key, _value) unless self.errors.added?(key, _value)
41
- end
42
- end
43
- end
44
-
45
- end
46
- end
@@ -1,33 +0,0 @@
1
- module ActiveModel
2
-
3
- module Validations
4
-
5
- class NestedUniquenessValidator < EachValidator
6
- def validate_each(record, attr_name, value)
7
- uniq_value, existing_objects, first_element = options[:uniq_value], [], nil
8
-
9
- record.send(attr_name).each do |object|
10
- next if Helpers.marked_for_destruction?(object)
11
-
12
- first_element = object if first_element.nil?
13
-
14
- if existing_objects.include?(object.send(uniq_value))
15
- object.errors.add(uniq_value, :taken)
16
- record.errors.add(attr_name, :taken)
17
- else
18
- existing_objects << object.send(uniq_value)
19
- end
20
- end
21
-
22
- end
23
- end
24
-
25
- module HelperMethods
26
-
27
- def validates_nested_uniqueness(*attr_names)
28
- validates_with NestedUniquenessValidator, _merge_attributes(attr_names)
29
- end
30
-
31
- end
32
- end
33
- end