active_type 0.4.5 → 0.7.5

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +30 -24
  5. data/CHANGELOG.md +73 -2
  6. data/README.md +56 -11
  7. data/Rakefile +22 -1
  8. data/active_type.gemspec +2 -1
  9. data/gemfiles/Gemfile.3.2.mysql2 +1 -0
  10. data/gemfiles/Gemfile.3.2.mysql2.lock +4 -2
  11. data/gemfiles/Gemfile.3.2.sqlite3 +1 -0
  12. data/gemfiles/Gemfile.3.2.sqlite3.lock +4 -2
  13. data/gemfiles/Gemfile.4.0.sqlite3 +1 -0
  14. data/gemfiles/Gemfile.4.0.sqlite3.lock +4 -2
  15. data/gemfiles/Gemfile.4.1.sqlite3 +1 -0
  16. data/gemfiles/Gemfile.4.1.sqlite3.lock +4 -2
  17. data/gemfiles/Gemfile.4.2.1.mysql2 +1 -0
  18. data/gemfiles/Gemfile.4.2.1.mysql2.lock +4 -2
  19. data/gemfiles/Gemfile.4.2.1.pg +1 -0
  20. data/gemfiles/Gemfile.4.2.1.pg.lock +4 -2
  21. data/gemfiles/Gemfile.4.2.1.sqlite3 +1 -0
  22. data/gemfiles/Gemfile.4.2.1.sqlite3.lock +4 -2
  23. data/gemfiles/Gemfile.5.0.0.mysql2.lock +56 -0
  24. data/gemfiles/Gemfile.5.0.0.pg.lock +56 -0
  25. data/gemfiles/Gemfile.5.0.0.sqlite3 +8 -0
  26. data/gemfiles/Gemfile.5.0.0.sqlite3.lock +56 -0
  27. data/gemfiles/Gemfile.5.1.0.mysql2 +8 -0
  28. data/gemfiles/Gemfile.5.1.0.mysql2.lock +56 -0
  29. data/gemfiles/Gemfile.5.1.0.pg +8 -0
  30. data/gemfiles/Gemfile.5.1.0.pg.lock +56 -0
  31. data/gemfiles/Gemfile.5.1.0.sqlite3 +8 -0
  32. data/gemfiles/Gemfile.5.1.0.sqlite3.lock +56 -0
  33. data/lib/active_type/extended_record/inheritance.rb +41 -6
  34. data/lib/active_type/nested_attributes/association.rb +13 -4
  35. data/lib/active_type/nested_attributes/builder.rb +3 -3
  36. data/lib/active_type/nested_attributes/nests_many_association.rb +5 -1
  37. data/lib/active_type/nested_attributes/nests_one_association.rb +3 -2
  38. data/lib/active_type/no_table.rb +129 -42
  39. data/lib/active_type/type_caster.rb +66 -25
  40. data/lib/active_type/util.rb +21 -6
  41. data/lib/active_type/version.rb +1 -1
  42. data/lib/active_type/virtual_attributes.rb +23 -1
  43. data/lib/active_type.rb +13 -3
  44. metadata +16 -55
  45. data/spec/active_type/extended_record/single_table_inheritance_spec.rb +0 -62
  46. data/spec/active_type/extended_record_spec.rb +0 -233
  47. data/spec/active_type/nested_attributes_spec.rb +0 -700
  48. data/spec/active_type/object_spec.rb +0 -400
  49. data/spec/active_type/record_spec.rb +0 -236
  50. data/spec/active_type/util_spec.rb +0 -128
  51. data/spec/integration/holidays_spec.rb +0 -102
  52. data/spec/integration/shape_spec.rb +0 -110
  53. data/spec/integration/sign_in_spec.rb +0 -101
  54. data/spec/integration/sign_up_spec.rb +0 -102
  55. data/spec/shared_examples/accessors.rb +0 -41
  56. data/spec/shared_examples/belongs_to.rb +0 -17
  57. data/spec/shared_examples/coercible_columns.rb +0 -228
  58. data/spec/shared_examples/constructor.rb +0 -30
  59. data/spec/shared_examples/defaults.rb +0 -60
  60. data/spec/shared_examples/dirty_tracking.rb +0 -40
  61. data/spec/shared_examples/dupable.rb +0 -31
  62. data/spec/shared_examples/mass_assignment.rb +0 -26
  63. data/spec/spec_helper.rb +0 -27
  64. data/spec/support/database.rb +0 -55
  65. data/spec/support/database.sample.yml +0 -3
  66. data/spec/support/error_on.rb +0 -12
  67. data/spec/support/i18n.rb +0 -1
  68. data/spec/support/protected_params.rb +0 -20
  69. data/spec/support/time_zone.rb +0 -1
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ active_type (0.7.0)
5
+ activerecord (>= 3.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.0.0)
11
+ activesupport (= 5.0.0)
12
+ activerecord (5.0.0)
13
+ activemodel (= 5.0.0)
14
+ activesupport (= 5.0.0)
15
+ arel (~> 7.0)
16
+ activesupport (5.0.0)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (~> 0.7)
19
+ minitest (~> 5.1)
20
+ tzinfo (~> 1.1)
21
+ arel (7.0.0)
22
+ concurrent-ruby (1.0.2)
23
+ diff-lcs (1.2.5)
24
+ i18n (0.7.0)
25
+ minitest (5.9.0)
26
+ pg (0.18.4)
27
+ rake (10.4.2)
28
+ rspec (3.5.0)
29
+ rspec-core (~> 3.5.0)
30
+ rspec-expectations (~> 3.5.0)
31
+ rspec-mocks (~> 3.5.0)
32
+ rspec-core (3.5.0)
33
+ rspec-support (~> 3.5.0)
34
+ rspec-expectations (3.5.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.5.0)
37
+ rspec-mocks (3.5.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.5.0)
40
+ rspec-support (3.5.0)
41
+ thread_safe (0.3.5)
42
+ tzinfo (1.2.2)
43
+ thread_safe (~> 0.1)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ active_type!
50
+ activerecord (~> 5.0.0)
51
+ pg
52
+ rake
53
+ rspec (~> 3.4)
54
+
55
+ BUNDLED WITH
56
+ 1.12.1
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~>5.0.0'
4
+ gem 'rspec', '~> 3.4'
5
+ gem 'sqlite3'
6
+ gem 'rake'
7
+
8
+ gem 'active_type', :path => '..'
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ active_type (0.7.5)
5
+ activerecord (>= 3.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.0.0)
11
+ activesupport (= 5.0.0)
12
+ activerecord (5.0.0)
13
+ activemodel (= 5.0.0)
14
+ activesupport (= 5.0.0)
15
+ arel (~> 7.0)
16
+ activesupport (5.0.0)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (~> 0.7)
19
+ minitest (~> 5.1)
20
+ tzinfo (~> 1.1)
21
+ arel (7.0.0)
22
+ concurrent-ruby (1.0.2)
23
+ diff-lcs (1.2.5)
24
+ i18n (0.7.0)
25
+ minitest (5.9.0)
26
+ rake (10.4.2)
27
+ rspec (3.5.0)
28
+ rspec-core (~> 3.5.0)
29
+ rspec-expectations (~> 3.5.0)
30
+ rspec-mocks (~> 3.5.0)
31
+ rspec-core (3.5.0)
32
+ rspec-support (~> 3.5.0)
33
+ rspec-expectations (3.5.0)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.5.0)
36
+ rspec-mocks (3.5.0)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.5.0)
39
+ rspec-support (3.5.0)
40
+ sqlite3 (1.3.11)
41
+ thread_safe (0.3.5)
42
+ tzinfo (1.2.2)
43
+ thread_safe (~> 0.1)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ active_type!
50
+ activerecord (~> 5.0.0)
51
+ rake
52
+ rspec (~> 3.4)
53
+ sqlite3
54
+
55
+ BUNDLED WITH
56
+ 1.15.4
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~>5.1.0'
4
+ gem 'rspec', '~>3.4'
5
+ gem 'mysql2'
6
+ gem 'rake'
7
+
8
+ gem 'active_type', :path => '..'
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ active_type (0.7.5)
5
+ activerecord (>= 3.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.1.1)
11
+ activesupport (= 5.1.1)
12
+ activerecord (5.1.1)
13
+ activemodel (= 5.1.1)
14
+ activesupport (= 5.1.1)
15
+ arel (~> 8.0)
16
+ activesupport (5.1.1)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (~> 0.7)
19
+ minitest (~> 5.1)
20
+ tzinfo (~> 1.1)
21
+ arel (8.0.0)
22
+ concurrent-ruby (1.0.5)
23
+ diff-lcs (1.3)
24
+ i18n (0.8.4)
25
+ minitest (5.10.2)
26
+ mysql2 (0.4.6)
27
+ rake (12.0.0)
28
+ rspec (3.6.0)
29
+ rspec-core (~> 3.6.0)
30
+ rspec-expectations (~> 3.6.0)
31
+ rspec-mocks (~> 3.6.0)
32
+ rspec-core (3.6.0)
33
+ rspec-support (~> 3.6.0)
34
+ rspec-expectations (3.6.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.6.0)
37
+ rspec-mocks (3.6.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.6.0)
40
+ rspec-support (3.6.0)
41
+ thread_safe (0.3.6)
42
+ tzinfo (1.2.3)
43
+ thread_safe (~> 0.1)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ active_type!
50
+ activerecord (~> 5.1.0)
51
+ mysql2
52
+ rake
53
+ rspec (~> 3.4)
54
+
55
+ BUNDLED WITH
56
+ 1.15.4
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~>5.1.0'
4
+ gem 'rspec', '~>3.4'
5
+ gem 'pg'
6
+ gem 'rake'
7
+
8
+ gem 'active_type', :path => '..'
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ active_type (0.7.5)
5
+ activerecord (>= 3.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.1.1)
11
+ activesupport (= 5.1.1)
12
+ activerecord (5.1.1)
13
+ activemodel (= 5.1.1)
14
+ activesupport (= 5.1.1)
15
+ arel (~> 8.0)
16
+ activesupport (5.1.1)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (~> 0.7)
19
+ minitest (~> 5.1)
20
+ tzinfo (~> 1.1)
21
+ arel (8.0.0)
22
+ concurrent-ruby (1.0.5)
23
+ diff-lcs (1.3)
24
+ i18n (0.8.4)
25
+ minitest (5.10.2)
26
+ pg (0.21.0)
27
+ rake (12.0.0)
28
+ rspec (3.6.0)
29
+ rspec-core (~> 3.6.0)
30
+ rspec-expectations (~> 3.6.0)
31
+ rspec-mocks (~> 3.6.0)
32
+ rspec-core (3.6.0)
33
+ rspec-support (~> 3.6.0)
34
+ rspec-expectations (3.6.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.6.0)
37
+ rspec-mocks (3.6.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.6.0)
40
+ rspec-support (3.6.0)
41
+ thread_safe (0.3.6)
42
+ tzinfo (1.2.3)
43
+ thread_safe (~> 0.1)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ active_type!
50
+ activerecord (~> 5.1.0)
51
+ pg
52
+ rake
53
+ rspec (~> 3.4)
54
+
55
+ BUNDLED WITH
56
+ 1.15.4
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~>5.1.0'
4
+ gem 'rspec', '~> 3.4'
5
+ gem 'sqlite3'
6
+ gem 'rake'
7
+
8
+ gem 'active_type', :path => '..'
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ active_type (0.7.5)
5
+ activerecord (>= 3.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.1.1)
11
+ activesupport (= 5.1.1)
12
+ activerecord (5.1.1)
13
+ activemodel (= 5.1.1)
14
+ activesupport (= 5.1.1)
15
+ arel (~> 8.0)
16
+ activesupport (5.1.1)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (~> 0.7)
19
+ minitest (~> 5.1)
20
+ tzinfo (~> 1.1)
21
+ arel (8.0.0)
22
+ concurrent-ruby (1.0.5)
23
+ diff-lcs (1.3)
24
+ i18n (0.8.4)
25
+ minitest (5.10.2)
26
+ rake (12.0.0)
27
+ rspec (3.6.0)
28
+ rspec-core (~> 3.6.0)
29
+ rspec-expectations (~> 3.6.0)
30
+ rspec-mocks (~> 3.6.0)
31
+ rspec-core (3.6.0)
32
+ rspec-support (~> 3.6.0)
33
+ rspec-expectations (3.6.0)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.6.0)
36
+ rspec-mocks (3.6.0)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.6.0)
39
+ rspec-support (3.6.0)
40
+ sqlite3 (1.3.13)
41
+ thread_safe (0.3.6)
42
+ tzinfo (1.2.3)
43
+ thread_safe (~> 0.1)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ active_type!
50
+ activerecord (~> 5.1.0)
51
+ rake
52
+ rspec (~> 3.4)
53
+ sqlite3
54
+
55
+ BUNDLED WITH
56
+ 1.15.4
@@ -23,13 +23,48 @@ module ActiveType
23
23
 
24
24
  private
25
25
 
26
- def find_sti_class(type_name)
27
- sti_class = super
28
- if self <= sti_class
29
- self
30
- else
31
- sti_class
26
+ if ActiveRecord::VERSION::MAJOR < 5
27
+
28
+ def find_sti_class(type_name)
29
+ sti_class = super
30
+ if self <= sti_class
31
+ self
32
+ else
33
+ sti_class
34
+ end
32
35
  end
36
+
37
+ else
38
+
39
+ # Rails 5 find_sti_class does a sanity check for proper inheritance that fails for
40
+ # our usecase
41
+ # copied from activerecord/lib/active_record/inheritance.rb
42
+ def find_sti_class(type_name)
43
+ type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
44
+ subclass = begin
45
+ if store_full_sti_class
46
+ ActiveSupport::Dependencies.constantize(type_name)
47
+ else
48
+ compute_type(type_name)
49
+ end
50
+ rescue NameError
51
+ raise ActiveRecord::SubclassNotFound,
52
+ "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
53
+ "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
54
+ "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
55
+ "or overwrite #{name}.inheritance_column to use another column for that information."
56
+ end
57
+ #### our code starts here
58
+ if self <= subclass
59
+ subclass = self
60
+ end
61
+ #### our code ends here
62
+ unless subclass == self || descendants.include?(subclass)
63
+ raise ActiveRecord::SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
64
+ end
65
+ subclass
66
+ end
67
+
33
68
  end
34
69
 
35
70
  end
@@ -9,13 +9,18 @@ module ActiveType
9
9
  class Association
10
10
 
11
11
  def initialize(owner, target_name, options = {})
12
- options.assert_valid_keys(:build_scope, :find_scope, :scope, :allow_destroy, :reject_if)
12
+ options.assert_valid_keys(*valid_options)
13
13
 
14
14
  @owner = owner
15
15
  @target_name = target_name.to_sym
16
16
  @allow_destroy = options.fetch(:allow_destroy, false)
17
17
  @reject_if = options.delete(:reject_if)
18
18
  @options = options.dup
19
+ @index_errors = if ActiveRecord::VERSION::MAJOR < 5
20
+ @options[:index_errors]
21
+ else
22
+ @options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors
23
+ end
19
24
  end
20
25
 
21
26
  def assign_attributes(parent, attributes)
@@ -36,10 +41,10 @@ module ActiveType
36
41
  end
37
42
 
38
43
  def validate(parent)
39
- changed_children(parent).each do |child|
44
+ changed_children(parent).each_with_index do |child, index|
40
45
  unless child.valid?
41
46
  child.errors.each do |attribute, message|
42
- attribute = "#{@target_name}.#{attribute}"
47
+ attribute = @index_errors ? "#{@target_name}[#{index}].#{attribute}" : "#{@target_name}.#{attribute}"
43
48
  parent.errors[attribute] << message
44
49
  parent.errors[attribute].uniq!
45
50
  end
@@ -106,7 +111,7 @@ module ActiveType
106
111
  end
107
112
 
108
113
  def truthy?(value)
109
- @boolean_type_caster ||= TypeCaster.get(:boolean, @owner.connection)
114
+ @boolean_type_caster ||= TypeCaster.get(:boolean)
110
115
  @boolean_type_caster.type_cast_from_user(value)
111
116
  end
112
117
 
@@ -122,6 +127,10 @@ module ActiveType
122
127
  result
123
128
  end
124
129
 
130
+ def valid_options
131
+ [:build_scope, :find_scope, :scope, :allow_destroy, :reject_if]
132
+ end
133
+
125
134
  end
126
135
 
127
136
  end
@@ -28,7 +28,7 @@ module ActiveType
28
28
  end
29
29
 
30
30
  def add_attribute(name, options)
31
- @owner.attribute(name, options)
31
+ @owner.attribute(name, :object, options)
32
32
  end
33
33
 
34
34
  def add_writer_method(name, association)
@@ -41,7 +41,7 @@ module ActiveType
41
41
  end
42
42
 
43
43
  def add_autosave(name, association)
44
- save_method = "save_associated_records_for_#{name}"
44
+ save_method = :"save_associated_records_for_#{name}"
45
45
  @module.module_eval do
46
46
  define_method save_method do
47
47
  association.save(self)
@@ -51,7 +51,7 @@ module ActiveType
51
51
  end
52
52
 
53
53
  def add_validation(name, association)
54
- validate_method = "validate_associated_records_for_#{name}"
54
+ validate_method = :"validate_associated_records_for_#{name}"
55
55
  @module.module_eval do
56
56
  define_method validate_method do
57
57
  association.validate(self)
@@ -31,7 +31,7 @@ module ActiveType
31
31
  destroy = truthy?(attributes.delete(:_destroy)) && @allow_destroy
32
32
 
33
33
  if id = attributes.delete(:id)
34
- child = fetch_child(parent, id.to_i)
34
+ child = fetch_child(parent, id)
35
35
  if destroy
36
36
  child.mark_for_destruction
37
37
  else
@@ -64,6 +64,10 @@ module ActiveType
64
64
  @target_name.to_s.classify
65
65
  end
66
66
 
67
+ def valid_options
68
+ super + [:index_errors]
69
+ end
70
+
67
71
  end
68
72
 
69
73
  end
@@ -17,9 +17,10 @@ module ActiveType
17
17
  destroy = truthy?(attributes.delete(:_destroy)) && @allow_destroy
18
18
 
19
19
  if id = attributes.delete(:id)
20
- assigned_child ||= fetch_child(parent, id.to_i)
20
+ assigned_child ||= fetch_child(parent, id)
21
21
  if assigned_child
22
- if assigned_child.id == id.to_i
22
+ assigned_child.id = id
23
+ if assigned_child.id == assigned_child.id_was
23
24
  assigned_child.attributes = attributes
24
25
  else
25
26
  raise AssignmentError, "child record '#{@target_name}' did not match id '#{id}'"