trax_model 0.0.91 → 0.0.92

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/lib/trax/model.rb +71 -12
  4. data/lib/trax/model/attributes.rb +40 -0
  5. data/lib/trax/model/attributes/definitions.rb +19 -0
  6. data/lib/trax/model/attributes/errors.rb +15 -0
  7. data/lib/trax/model/attributes/mixin.rb +43 -0
  8. data/lib/trax/model/attributes/type.rb +11 -0
  9. data/lib/trax/model/attributes/types.rb +11 -0
  10. data/lib/trax/model/attributes/types/array.rb +92 -0
  11. data/lib/trax/model/attributes/types/enum.rb +32 -0
  12. data/lib/trax/model/attributes/types/json.rb +76 -0
  13. data/lib/trax/model/attributes/types/uuid_array.rb +83 -0
  14. data/lib/trax/model/attributes/value.rb +9 -0
  15. data/lib/trax/model/config.rb +1 -9
  16. data/lib/trax/model/enum.rb +3 -3
  17. data/lib/trax/model/errors.rb +30 -19
  18. data/lib/trax/model/freezable.rb +1 -1
  19. data/lib/trax/model/mixin.rb +16 -4
  20. data/lib/trax/model/railtie.rb +17 -0
  21. data/lib/trax/model/registry.rb +3 -3
  22. data/lib/trax/model/restorable.rb +26 -17
  23. data/lib/trax/model/struct.rb +31 -0
  24. data/lib/trax/model/unique_id.rb +56 -14
  25. data/lib/trax/model/uuid_array.rb +59 -0
  26. data/lib/trax/model/validators.rb +2 -0
  27. data/lib/trax/validators/boolean_validator.rb +14 -0
  28. data/lib/trax/validators/email_validator.rb +6 -2
  29. data/lib/trax/validators/enum_validator.rb +16 -0
  30. data/lib/trax/validators/json_attribute_validator.rb +19 -0
  31. data/lib/trax_model/version.rb +1 -1
  32. data/spec/support/schema.rb +26 -10
  33. data/spec/trax/model/struct_spec.rb +16 -0
  34. data/spec/trax/model_spec.rb +2 -4
  35. data/trax_model.gemspec +1 -0
  36. metadata +35 -2
@@ -0,0 +1,59 @@
1
+ module Trax
2
+ module Model
3
+ class UUIDArray
4
+ include Enumerable
5
+
6
+ attr_reader :uuids
7
+
8
+ def initialize(*uuids)
9
+ @uuids = uuids.map{ |uuid_string| uuid_string.try(&:uuid) }.compact
10
+ end
11
+
12
+ def each(&block)
13
+ yield @uuids.each(&block)
14
+ end
15
+
16
+ def <<(val)
17
+ reset_instance_variables(:record_types, :records_grouped_by_count, :records_grouped_by_uuid)
18
+ @uuids.push(::Trax::Model::UUID.new(val))
19
+ end
20
+
21
+ def records
22
+ @records ||= group_by_record_type.to_a.map{|pair|
23
+ pair[0].by_id(*pair[1])
24
+ }.flatten.compact
25
+ end
26
+
27
+ def records_grouped_by_uuid
28
+ @records_grouped_by_uuid ||= records.group_by(&:id)
29
+ end
30
+
31
+ def records_grouped_by_count
32
+ @records_grouped_by_count ||= begin
33
+ {}.tap do |hash|
34
+ @uuids.group_by_count.each_pair do |uuid, count|
35
+ record = records_grouped_by_uuid[uuid].first
36
+ hash[record] = count
37
+ end
38
+
39
+ hash
40
+ end
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def group_by_count
47
+ @uuids.group_by(&:count)
48
+ end
49
+
50
+ def group_by_record_type
51
+ @uuids.group_by{ |uuid| uuid.record_type }
52
+ end
53
+
54
+ def record_types
55
+ @record_types ||= @uuids.map(&:record_type).flatten.compact.uniq
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,7 +3,9 @@ module Trax
3
3
  module Validators
4
4
  extend ::ActiveSupport::Autoload
5
5
 
6
+ autoload :BooleanValidator
6
7
  autoload :EmailValidator
8
+ autoload :EnumValidator
7
9
  autoload :Frozen
8
10
  autoload :FutureDate
9
11
  autoload :Subdomain
@@ -0,0 +1,14 @@
1
+ ### Credit to Jason Staten, https://github.com/statianzo
2
+ class BooleanValidator < ActiveModel::Validations::InclusionValidator
3
+ def initialize(options)
4
+ options[:in] = [true, false].to_set
5
+ options[:message] = "must be true or false"
6
+ super
7
+ end
8
+
9
+ module HelperMethods
10
+ def validates_booleans(*attr_names)
11
+ validates_with(::BooleanValidator, _merge_attributes(attr_names))
12
+ end
13
+ end
14
+ end
@@ -1,6 +1,10 @@
1
1
  class EmailValidator < ActiveModel::EachValidator
2
+ EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
3
+
2
4
  def validate_each(record, attribute, value)
3
- record.errors.add attribute, (options[:message] || "is not a valid email") unless
4
- value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
5
+ unless (value =~ EMAIL_REGEX).present?
6
+ record.errors[attribute] = (options[:message] || "is not a valid email")
7
+ end
8
+ record
5
9
  end
6
10
  end
@@ -0,0 +1,16 @@
1
+ class EnumValidator < ActiveModel::EachValidator
2
+ def validate_each(object, attribute, value)
3
+ enum_attribute = object.class.trax_attribute_fields[:enum][attribute]
4
+
5
+ unless value.is_a?(enum_attribute) && value.valid?
6
+ if value.is_a?(enum_attribute)
7
+ value.errors.messages.each_pair do |k,v|
8
+ v = v.join(", ") if v.is_a?(Array)
9
+ object.errors["#{attribute}.#{k}"] = v
10
+ end
11
+ else
12
+ object.errors[attribute] = "#{v} is not an allowed value"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # validates each json property and bubbles up any errors
2
+ # also throws a generic can not be blank error, in the event
3
+ # that a hash is not provided
4
+ class JsonAttributeValidator < ActiveModel::EachValidator
5
+ def validate_each(object, attribute, value)
6
+ json_attribute = object.class.trax_attribute_fields[:json][attribute]
7
+
8
+ unless value.is_a?(json_attribute) && value.valid?
9
+ if value.is_a?(json_attribute)
10
+ value.errors.messages.each_pair do |k,v|
11
+ v = v.join(", ") if v.is_a?(Array)
12
+ object.errors.add(:"#{attribute}.#{k}", v)
13
+ end
14
+ else
15
+ object.errors[attribute] << "can not be blank"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module TraxModel
2
- VERSION = '0.0.91'
2
+ VERSION = '0.0.92'
3
3
  end
@@ -36,7 +36,8 @@ ActiveRecord::Schema.define(:version => 1) do
36
36
  end
37
37
 
38
38
  create_table "widgets", :force => true do |t|
39
- t.string "email_address"
39
+ t.string "uuid"
40
+ t.string "email_address"
40
41
  t.string "subdomain"
41
42
  t.string "website"
42
43
  t.integer "status"
@@ -77,15 +78,20 @@ end
77
78
 
78
79
  class Product < ::ActiveRecord::Base
79
80
  include ::Trax::Model
80
- include ::Trax::Model::UniqueId
81
81
 
82
- defaults :uuid_prefix => "1a", :uuid_column => "uuid"
82
+ mixins :unique_id => {
83
+ :uuid_column => "uuid",
84
+ :uuid_prefix => "1a"
85
+ }
83
86
  end
84
87
 
85
88
  class Widget < ::ActiveRecord::Base
86
89
  include ::Trax::Model
87
90
 
88
- defaults :uuid_prefix => "2a", :uuid_column => "uuid"
91
+ mixins :unique_id => {
92
+ :uuid_column => "uuid",
93
+ :uuid_prefix => "2a"
94
+ }
89
95
 
90
96
  validates :subdomain, :subdomain => true, :allow_nil => true
91
97
  validates :email_address, :email => true, :allow_nil => true
@@ -95,12 +101,11 @@ end
95
101
  class Message < ::ActiveRecord::Base
96
102
  include ::Trax::Model
97
103
 
98
- defaults :uuid_prefix => "3a", :uuid_column => "uuid"
99
-
100
- mixins :freezable => true,
104
+ mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "3a" },
105
+ :freezable => true,
101
106
  :restorable => { :field => :deleted }
102
107
 
103
- enum :status => [:queued, :scheduled, :delivered, :failed_delivery]
108
+ enum :status => [ :queued, :scheduled, :delivered, :failed_delivery ]
104
109
 
105
110
  default_value_for :status do
106
111
  self.statuses[:queued]
@@ -114,13 +119,13 @@ end
114
119
  class Thing < ::ActiveRecord::Base
115
120
  include ::Trax::Model
116
121
 
117
- defaults :uuid_prefix => "4a", :uuid_column => "uuid"
122
+ mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "4a" }
118
123
  end
119
124
 
120
125
  class Person < ::ActiveRecord::Base
121
126
  include ::Trax::Model
122
127
 
123
- defaults :uuid_column => "uuid"
128
+ mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "5a" }
124
129
  end
125
130
 
126
131
  class Stapler < ::ActiveRecord::Base
@@ -133,3 +138,14 @@ end
133
138
 
134
139
  class SwinglineStaplerAttributeSet < ::ActiveRecord::Base
135
140
  end
141
+
142
+ require 'trax/model/struct'
143
+
144
+ class StoreCategory < ::Trax::Model::Struct
145
+ property :name
146
+
147
+ struct_property :meta_attributes do
148
+ property :description
149
+ property :keywords
150
+ end
151
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ describe ::Trax::Model::Struct do
3
+ subject {
4
+ ::StoreCategory.new(
5
+ "name" => "watches",
6
+ "meta_attributes" => {
7
+ "description" => "Watches and stuff",
8
+ "keywords" => [ 'nixon', 'vestal' ]
9
+ }
10
+ )
11
+ }
12
+
13
+ its("name") { should eq "watches" }
14
+ its("meta_attributes.description") { should eq "Watches and stuff" }
15
+ its("meta_attributes.class") { should eq StoreCategory::MetaAttributesStruct }
16
+ end
@@ -1,10 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ::Trax::Model do
4
- subject do
5
- ::Product
6
- end
4
+ subject { ::Product }
7
5
 
8
6
  its(:trax_registry_key) { should eq "product" }
9
- its(:trax_defaults) { should be_a(::Trax::Model::Config) }
7
+ it { subject.unique_id_config.uuid_prefix }
10
8
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "trax_core", "~> 0.0.3"
22
22
  spec.add_dependency "default_value_for", "~> 3.0.0"
23
23
  spec.add_dependency "simple_enum"
24
+ spec.add_development_dependency "hashie", "~> 3.4.1"
24
25
  spec.add_development_dependency "activerecord"
25
26
  spec.add_development_dependency "bundler", "~> 1.6"
26
27
  spec.add_development_dependency "rake"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trax_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.91
4
+ version: 0.0.92
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Ayre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-18 00:00:00.000000000 Z
11
+ date: 2015-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trax_core
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hashie
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.4.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.4.1
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: activerecord
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -279,6 +293,17 @@ files:
279
293
  - Rakefile
280
294
  - lib/trax.rb
281
295
  - lib/trax/model.rb
296
+ - lib/trax/model/attributes.rb
297
+ - lib/trax/model/attributes/definitions.rb
298
+ - lib/trax/model/attributes/errors.rb
299
+ - lib/trax/model/attributes/mixin.rb
300
+ - lib/trax/model/attributes/type.rb
301
+ - lib/trax/model/attributes/types.rb
302
+ - lib/trax/model/attributes/types/array.rb
303
+ - lib/trax/model/attributes/types/enum.rb
304
+ - lib/trax/model/attributes/types/json.rb
305
+ - lib/trax/model/attributes/types/uuid_array.rb
306
+ - lib/trax/model/attributes/value.rb
282
307
  - lib/trax/model/config.rb
283
308
  - lib/trax/model/enum.rb
284
309
  - lib/trax/model/errors.rb
@@ -289,18 +314,24 @@ files:
289
314
  - lib/trax/model/mti/abstract.rb
290
315
  - lib/trax/model/mti/entity.rb
291
316
  - lib/trax/model/mti/namespace.rb
317
+ - lib/trax/model/railtie.rb
292
318
  - lib/trax/model/registry.rb
293
319
  - lib/trax/model/restorable.rb
294
320
  - lib/trax/model/sti.rb
295
321
  - lib/trax/model/sti/attributes.rb
322
+ - lib/trax/model/struct.rb
296
323
  - lib/trax/model/unique_id.rb
297
324
  - lib/trax/model/uuid.rb
325
+ - lib/trax/model/uuid_array.rb
298
326
  - lib/trax/model/uuid_prefix.rb
299
327
  - lib/trax/model/validators.rb
300
328
  - lib/trax/string.rb
329
+ - lib/trax/validators/boolean_validator.rb
301
330
  - lib/trax/validators/email_validator.rb
331
+ - lib/trax/validators/enum_validator.rb
302
332
  - lib/trax/validators/frozen_validator.rb
303
333
  - lib/trax/validators/future_validator.rb
334
+ - lib/trax/validators/json_attribute_validator.rb
304
335
  - lib/trax/validators/subdomain_validator.rb
305
336
  - lib/trax/validators/url_validator.rb
306
337
  - lib/trax_model.rb
@@ -314,6 +345,7 @@ files:
314
345
  - spec/trax/model/registry_spec.rb
315
346
  - spec/trax/model/restorable_spec.rb
316
347
  - spec/trax/model/sti/attributes_spec.rb
348
+ - spec/trax/model/struct_spec.rb
317
349
  - spec/trax/model/unique_id_spec.rb
318
350
  - spec/trax/model/uuid_prefix_spec.rb
319
351
  - spec/trax/model/uuid_spec.rb
@@ -358,6 +390,7 @@ test_files:
358
390
  - spec/trax/model/registry_spec.rb
359
391
  - spec/trax/model/restorable_spec.rb
360
392
  - spec/trax/model/sti/attributes_spec.rb
393
+ - spec/trax/model/struct_spec.rb
361
394
  - spec/trax/model/unique_id_spec.rb
362
395
  - spec/trax/model/uuid_prefix_spec.rb
363
396
  - spec/trax/model/uuid_spec.rb