trax_model 0.0.91 → 0.0.92

Sign up to get free protection for your applications and to get access to all the features.
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