trax_model 0.0.98 → 0.0.99

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/lib/trax/model.rb +6 -16
  4. data/lib/trax/model/attributes.rb +1 -1
  5. data/lib/trax/model/attributes/definitions.rb +4 -0
  6. data/lib/trax/model/attributes/{mixin.rb → dsl.rb} +2 -12
  7. data/lib/trax/model/attributes/types/boolean.rb +1 -2
  8. data/lib/trax/model/attributes/types/enum.rb +0 -2
  9. data/lib/trax/model/attributes/types/integer.rb +2 -2
  10. data/lib/trax/model/attributes/types/set.rb +67 -0
  11. data/lib/trax/model/attributes/types/string.rb +3 -3
  12. data/lib/trax/model/attributes/types/struct.rb +5 -3
  13. data/lib/trax/model/attributes/types/uuid_array.rb +0 -2
  14. data/lib/trax/model/{sti.rb → core_extensions.rb} +2 -2
  15. data/lib/trax/model/core_extensions/string.rb +17 -0
  16. data/lib/trax/model/extensions_for.rb +18 -0
  17. data/lib/trax/model/extensions_for/base.rb +31 -0
  18. data/lib/trax/model/extensions_for/boolean.rb +29 -0
  19. data/lib/trax/model/extensions_for/enumerable.rb +18 -0
  20. data/lib/trax/model/extensions_for/integer.rb +10 -0
  21. data/lib/trax/model/extensions_for/numeric.rb +46 -0
  22. data/lib/trax/model/extensions_for/set.rb +10 -0
  23. data/lib/trax/model/extensions_for/string.rb +30 -0
  24. data/lib/trax/model/extensions_for/struct.rb +191 -0
  25. data/lib/trax/model/extensions_for/struct_fields.rb +21 -0
  26. data/lib/trax/model/extensions_for/struct_fields/boolean.rb +32 -0
  27. data/lib/trax/model/extensions_for/struct_fields/enum.rb +20 -0
  28. data/lib/trax/model/extensions_for/struct_fields/float.rb +12 -0
  29. data/lib/trax/model/extensions_for/struct_fields/integer.rb +12 -0
  30. data/lib/trax/model/extensions_for/struct_fields/numeric.rb +52 -0
  31. data/lib/trax/model/extensions_for/struct_fields/string.rb +29 -0
  32. data/lib/trax/model/extensions_for/struct_fields/time.rb +54 -0
  33. data/lib/trax/model/matchable.rb +3 -10
  34. data/lib/trax/model/mixins.rb +3 -0
  35. data/lib/trax/model/mixins/freezable.rb +31 -0
  36. data/lib/trax/model/mixins/restorable.rb +63 -0
  37. data/lib/trax/model/mixins/sti_enum.rb +4 -5
  38. data/lib/trax/model/mixins/unique_id.rb +85 -0
  39. data/lib/trax/model/railtie.rb +4 -2
  40. data/lib/trax/validators/json_attribute_validator.rb +1 -0
  41. data/lib/trax_model/version.rb +1 -1
  42. data/spec/db/schema/default_tables.rb +1 -17
  43. data/spec/db/schema/pg_tables.rb +15 -0
  44. data/spec/support/models.rb +11 -16
  45. data/spec/support/pg/models.rb +31 -6
  46. data/spec/trax/model/attributes/types/set_spec.rb +68 -0
  47. data/spec/trax/model/attributes/types/struct_spec.rb +6 -0
  48. data/spec/trax/model/extensions_for/boolean_spec.rb +26 -0
  49. data/spec/trax/model/extensions_for/numeric_spec.rb +53 -0
  50. data/spec/trax/model/extensions_for/string_spec.rb +25 -0
  51. data/spec/trax/model/extensions_for/struct_spec.rb +223 -0
  52. data/spec/trax/model/extensions_for_spec.rb +0 -0
  53. data/spec/trax/model/{freezable_spec.rb → mixins/freezable_spec.rb} +1 -1
  54. data/spec/trax/model/{restorable_spec.rb → mixins/restorable_spec.rb} +1 -1
  55. data/spec/trax/model/{unique_id_spec.rb → mixins/unique_id_spec.rb} +1 -1
  56. data/trax_model.gemspec +4 -5
  57. metadata +49 -59
  58. data/lib/trax/model/enum.rb +0 -64
  59. data/lib/trax/model/freezable.rb +0 -29
  60. data/lib/trax/model/mti.rb +0 -11
  61. data/lib/trax/model/mti/abstract.rb +0 -65
  62. data/lib/trax/model/mti/entity.rb +0 -62
  63. data/lib/trax/model/mti/namespace.rb +0 -21
  64. data/lib/trax/model/restorable.rb +0 -61
  65. data/lib/trax/model/scopes.rb +0 -16
  66. data/lib/trax/model/sti/attributes.rb +0 -94
  67. data/lib/trax/model/string_extensions.rb +0 -11
  68. data/lib/trax/model/struct_extensions.rb +0 -185
  69. data/lib/trax/model/unique_id.rb +0 -83
  70. data/spec/trax/model/sti/attributes_spec.rb +0 -15
  71. data/spec/trax/model/struct_extensions_spec.rb +0 -16
@@ -0,0 +1,54 @@
1
+ module Trax
2
+ module Model
3
+ module ExtensionsFor
4
+ module StructFields
5
+ module Time
6
+ extend ::ActiveSupport::Concern
7
+ include ::Trax::Model::ExtensionsFor::Base
8
+
9
+ module ClassMethods
10
+ def after(value)
11
+ cast_type = 'timestamp'
12
+ operator = '>'
13
+ model_class.where("(#{parent_definition.field_name} ->> '#{field_name}')::#{cast_type} #{operator} ?", value)
14
+ end
15
+
16
+ def before(value)
17
+ cast_type = 'timestamp'
18
+ operator = '<'
19
+ model_class.where("(#{parent_definition.field_name} ->> '#{field_name}')::#{cast_type} #{operator} ?", value)
20
+ end
21
+
22
+ def between(first_time, second_time)
23
+ after(first_time).merge(before(second_time))
24
+ end
25
+
26
+ def gt(value)
27
+ after(value)
28
+ end
29
+
30
+ def gte(value)
31
+ cast_type = 'timestamp'
32
+ operator = '>='
33
+ model_class.where("(#{parent_definition.field_name} ->> '#{field_name}')::#{cast_type} #{operator} ?", value)
34
+ end
35
+
36
+ def in_range(first_time, second_time)
37
+ gte(first_time).merge(lte(second_time))
38
+ end
39
+
40
+ def lt(value)
41
+ before(value)
42
+ end
43
+
44
+ def lte(value)
45
+ cast_type = 'timestamp'
46
+ operator = '<='
47
+ model_class.where("(#{parent_definition.field_name} ->> '#{field_name}')::#{cast_type} #{operator} ?", value)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -3,23 +3,16 @@ module Trax
3
3
  module Matchable
4
4
  extend ::ActiveSupport::Concern
5
5
 
6
- included do
7
- ::String.class_eval do
8
- def to_matchable
9
- "%#{self.strip}%"
10
- end
11
- end
12
- end
13
-
14
6
  module ClassMethods
15
7
  def matching(args = {})
16
8
  matches = args.inject(self.all) do |scope, (key, value)|
17
9
  node = key.is_a?(Symbol) ? self.arel_table[key] : key
18
10
 
19
11
  values = [value]
12
+ values.flat_compact_uniq!
13
+ values.map!(&:to_matchable)
20
14
 
21
- match_values = values.flatten.compact.uniq.map!(&:to_matchable)
22
- scope = scope.where(node.matches_any(match_values))
15
+ scope = scope.where(node.matches_any(values))
23
16
  scope
24
17
  end
25
18
 
@@ -4,9 +4,12 @@ module Trax
4
4
  extend ::ActiveSupport::Autoload
5
5
 
6
6
  autoload :FieldScopes
7
+ autoload :Freezable
7
8
  autoload :IdScopes
9
+ autoload :Restorable
8
10
  autoload :SortByScopes
9
11
  autoload :StiEnum
12
+ autoload :UniqueId
10
13
  end
11
14
  end
12
15
  end
@@ -0,0 +1,31 @@
1
+ module Trax
2
+ module Model
3
+ module Mixins
4
+ module Freezable
5
+ extend ::Trax::Model::Mixin
6
+
7
+ included do
8
+ class_attribute :freezable_fields
9
+ self.freezable_fields = ::ActiveSupport::OrderedOptions.new
10
+ end
11
+
12
+ module ClassMethods
13
+ def freezable_by_enum(options = {})
14
+ freezable_fields.merge!(options)
15
+ define_frozen_validators_for_enum(options)
16
+ end
17
+
18
+ def define_frozen_validators_for_enum(options)
19
+ self.class_eval do
20
+ options.each_pair do |enum_method, frozen_states|
21
+ validates_with ::FrozenValidator, :if => lambda { |record|
22
+ frozen_states.any?{ |state| state == :"#{record.send(enum_method)}" } && !record.changed.include?("#{enum_method}")
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,63 @@
1
+ module Trax
2
+ module Model
3
+ module Mixins
4
+ module Restorable
5
+ extend ::Trax::Model::Mixin
6
+
7
+ define_configuration_options! do
8
+ option :field, :default => :is_deleted
9
+ option :timestamp_field, :default => :deleted_at
10
+ option :hide_deleted, :default => true
11
+ option :alias_destroy, :default => true
12
+ end
13
+
14
+ included do
15
+ define_configuration_options!(:restorable) do
16
+ option :field, :default => ::Trax::Model::Mixins::Restorable.config.field
17
+ option :timestamp_field, :default => ::Trax::Model::Mixins::Restorable.config.timestamp_field
18
+ option :hide_deleted, :default => ::Trax::Model::Mixins::Restorable.config.hide_deleted
19
+ option :alias_destroy, :default => ::Trax::Model::Mixins::Restorable.config.alias_destroy
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ def setup_restorable!
25
+ self.class_eval do
26
+ if(self.restorable_config.hide_deleted)
27
+ default_scope { by_not_deleted }
28
+ end
29
+
30
+ if(self.restorable_config.alias_destroy)
31
+ alias_method :destroy!, :destroy
32
+ end
33
+
34
+ ### Clear default deleted scope ###
35
+ scope :by_is_deleted, lambda { |*|
36
+ unscope(:where => self.restorable_config.field).where(self.restorable_config.field => true)
37
+ }
38
+ scope :by_not_deleted, lambda { |*|
39
+ where(self.restorable_config.field => false)
40
+ }
41
+
42
+ default_value_for(self.restorable_config.field) { false }
43
+ end
44
+ end
45
+ end
46
+
47
+ def destroy
48
+ self.update_attributes(self.class.restorable_config.field => true, self.class.restorable_config.timestamp_field => ::DateTime.now)
49
+ end
50
+
51
+ def restore
52
+ self.update_attributes(self.class.restorable_config.field => false, self.class.restorable_config.timestamp_field => ::DateTime.now)
53
+ end
54
+
55
+ def self.apply_mixin(target, options)
56
+ target.restorable_config.merge!(options)
57
+
58
+ target.setup_restorable!
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  module Trax
3
2
  module Model
4
3
  module Mixins
@@ -12,16 +11,16 @@ module Trax
12
11
  end
13
12
 
14
13
  included do
15
- after_initialize :set_type_from_kind, :unless => :type?, :if => :kind?
16
- after_initialize :set_kind_from_type, :unless => :kind?, :if => :type?
14
+ after_initialize :set_kind_from_type
15
+ after_initialize :set_type_from_kind
17
16
  end
18
17
 
19
18
  def set_type_from_kind
20
- self[:type] = self.class.kind_to_type_mapping[self[:kind]] if !self[:type]
19
+ self[:type] = self.class.kind_to_type_mapping[self[:kind]] if self.has_attribute?(:kind) && self.has_attribute?(:type) && !self[:type]
21
20
  end
22
21
 
23
22
  def set_kind_from_type
24
- self[:kind] = self.class.type_to_kind_mapping[self[:type]] if !self[:kind]
23
+ self[:kind] = self.class.type_to_kind_mapping[self[:type]] if self.has_attribute?(:kind) && self.has_attribute?(:type) && self.has_attribute?(:type) && !self[:kind]
25
24
  end
26
25
 
27
26
  module ClassMethods
@@ -0,0 +1,85 @@
1
+ module Trax
2
+ module Model
3
+ module Mixins
4
+ module UniqueId
5
+ extend ::Trax::Model::Mixin
6
+
7
+ define_configuration_options! do
8
+ option :uuid_column, :default => :id
9
+ option :uuid_map, :default => {}
10
+ end
11
+
12
+ after_included do |options|
13
+ define_configuration_options!(:unique_id) do
14
+ option :uuid_prefix,
15
+ :validates => {
16
+ :exclusion => {
17
+ :in => ::Trax::Model::Registry.uuid_map.values
18
+ },
19
+ :inclusion => {
20
+ :in => ::Trax::Model::UUIDPrefix.all,
21
+ :message => "%{value} not a valid uuid prefix!\nRun Trax::Model::UUIDPrefix.all for valid prefix list"
22
+ },
23
+ :allow_nil => true
24
+ }
25
+
26
+ option :uuid_column, :default => ::Trax::Model::Mixins::UniqueId.config.uuid_column
27
+
28
+ klass do
29
+ def uuid_prefix=(prefix)
30
+ if(::Trax::Model::Mixins::UniqueId.config.uuid_map.values.include?(prefix) && ::Trax::Model::Mixins::UniqueId.config.uuid_map[self.source.name] != prefix)
31
+ raise ::Trax::Model::Errors::DuplicatePrefixRegistered.new(:prefix => prefix, :model => self.source.name)
32
+ end
33
+
34
+ ::Trax::Model::Mixins::UniqueId.config.uuid_map[self.source.name] = prefix
35
+ super(::Trax::Model::UUIDPrefix.new(prefix))
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ #grab prefix from uuid registry if uuids are defined in an initializer
42
+ if ::Trax::Model.mixin_registry.key?(:unique_id) && ::Trax::Model::UUID.klass_prefix_map.key?(self.name)
43
+ self.unique_id_config.uuid_prefix = ::Trax::Model::UUID.klass_prefix_map[self.name]
44
+ end
45
+
46
+ self.unique_id_config.merge!(options)
47
+
48
+ if(self.unique_id_config.uuid_prefix)
49
+ default_value_for(:"#{self.unique_id_config.uuid_column}") {
50
+ ::Trax::Model::UUID.generate(self.unique_id_config.uuid_prefix)
51
+ }
52
+ end
53
+ end
54
+
55
+ def uuid
56
+ uuid_column = self.class.unique_id_config.uuid_column
57
+ uuid_value = (uuid_column == "uuid") ? super : __send__(uuid_column)
58
+
59
+ ::Trax::Model::UUID.new(uuid_value)
60
+ end
61
+
62
+ #i.e. Blog::Post
63
+ def uuid_type
64
+ uuid.record_type
65
+ end
66
+
67
+ #i.e. 'Blog::Post'
68
+ def uuid_type_name
69
+ uuid.record_type.name
70
+ end
71
+
72
+ #i.e, Blog::Post will = post
73
+ def uuid_type_slug
74
+ uuid.record_type.name.demodulize.underscore
75
+ end
76
+
77
+ module ClassMethods
78
+ def uuid_prefix
79
+ self.unique_id_config.uuid_prefix
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -3,8 +3,10 @@ module Trax
3
3
  class Railtie < ::Rails::Railtie
4
4
  ::ActiveSupport.on_load(:active_record) do
5
5
  def self.inherited(subklass)
6
- subklass.include(::Trax::Model) if ::Trax::Model.config.auto_include
7
- subklass.include(::Trax::Model::Attributes::Mixin) if ::Trax::Model.config.auto_include
6
+ if ::Trax::Model.config.auto_include
7
+ subklass.include(::Trax::Model)
8
+ subklass.include(::Trax::Model::Attributes::Dsl)
9
+ end
8
10
 
9
11
  super(subklass)
10
12
 
@@ -4,6 +4,7 @@
4
4
  class JsonAttributeValidator < ActiveModel::EachValidator
5
5
  def validate_each(object, attribute, value)
6
6
  json_attribute = object.class.fields_module[attribute]
7
+ value = json_attribute.new(value || {}) unless value.is_a?(json_attribute)
7
8
 
8
9
  value.instance_variable_set("@record", object)
9
10
 
@@ -1,3 +1,3 @@
1
1
  module TraxModel
2
- VERSION = '0.0.98'
2
+ VERSION = '0.0.99'
3
3
  end
@@ -4,7 +4,7 @@ DEFAULT_TABLES = Proc.new do
4
4
  t.integer "kind"
5
5
  t.integer "make"
6
6
  t.integer "model"
7
- t.string "uuid"
7
+ t.string "uuid"
8
8
  t.datetime "created_at", :null => false
9
9
  t.datetime "updated_at", :null => false
10
10
  end
@@ -58,20 +58,4 @@ DEFAULT_TABLES = Proc.new do
58
58
  t.datetime "created_at", :null => false
59
59
  t.datetime "updated_at", :null => false
60
60
  end
61
-
62
- create_table "staplers", :force => true do |t|
63
- t.string "name"
64
- t.string "type"
65
- t.integer "attribute_set_id"
66
- t.datetime "created_at", :null => false
67
- t.datetime "updated_at", :null => false
68
- end
69
-
70
- create_table "swingline_stapler_attribute_sets", :force => true do |t|
71
- t.float "speed"
72
- t.string "owner"
73
-
74
- t.datetime "created_at", :null => false
75
- t.datetime "updated_at", :null => false
76
- end
77
61
  end
@@ -16,6 +16,21 @@ PG_TABLES = Proc.new do
16
16
  t.datetime "updated_at", :null => false
17
17
  end
18
18
 
19
+ create_table "ecommerce_votes", :id => :uuid, :force => true do |t|
20
+ t.uuid "voteable_id"
21
+ t.jsonb "upvoter_ids"
22
+ t.jsonb "downvoter_ids"
23
+ t.datetime "created_at", :null => false
24
+ t.datetime "updated_at", :null => false
25
+ end
26
+
27
+ create_table "ecommerce_users", :id => :uuid, :force => true do |t|
28
+ t.string "name"
29
+ t.text "watched_product_ids", :array => true
30
+ t.datetime "created_at", :null => false
31
+ t.datetime "updated_at", :null => false
32
+ end
33
+
19
34
  create_table "ecommerce_product_attribute_sets", :id => :uuid, :force => true do |t|
20
35
  t.uuid "user_id"
21
36
  t.uuid "product_id"
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  class Product < ::ActiveRecord::Base
28
28
  include ::Trax::Model
29
- include ::Trax::Model::Attributes::Mixin
29
+ include ::Trax::Model::Attributes::Dsl
30
30
 
31
31
  mixins :unique_id => {
32
32
  :uuid_column => "uuid",
@@ -34,6 +34,12 @@ class Product < ::ActiveRecord::Base
34
34
  }
35
35
 
36
36
  define_attributes do
37
+ string :name
38
+ # float :price
39
+
40
+ integer :in_stock_quantity
41
+ integer :out_of_stock_quantity
42
+
37
43
  enum :status, :default => :in_stock do
38
44
  define :in_stock, 1
39
45
  define :out_of_stock, 2
@@ -47,12 +53,12 @@ end
47
53
  module Products
48
54
  class Shoes < Product
49
55
  include ::Trax::Model
50
- include ::Trax::Model::Attributes::Mixin
56
+ include ::Trax::Model::Attributes::Dsl
51
57
  end
52
58
 
53
59
  class MensShoes < Shoes
54
60
  include ::Trax::Model
55
- include ::Trax::Model::Attributes::Mixin
61
+ include ::Trax::Model::Attributes::Dsl
56
62
 
57
63
  define_attributes do
58
64
  enum :size, :default => :mens_9 do
@@ -72,7 +78,7 @@ end
72
78
 
73
79
  class Vehicle < ::ActiveRecord::Base
74
80
  include ::Trax::Model
75
- include ::Trax::Model::Attributes::Mixin
81
+ include ::Trax::Model::Attributes::Dsl
76
82
 
77
83
  mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "9c" },
78
84
  :sti_enum => true
@@ -138,19 +144,8 @@ class Person < ::ActiveRecord::Base
138
144
  mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "5a" }
139
145
  end
140
146
 
141
- class Stapler < ::ActiveRecord::Base
142
- include ::Trax::Model
143
- end
144
-
145
- class SwinglineStapler < ::Stapler
146
- include ::Trax::Model::STI::Attributes
147
- end
148
-
149
- class SwinglineStaplerAttributeSet < ::ActiveRecord::Base
150
- end
151
-
152
147
  class StoreCategory < ::Trax::Core::Types::Struct
153
- include ::Trax::Model::StructExtensions
148
+ include ::Trax::Model::ExtensionsFor::Struct
154
149
 
155
150
  string :name
156
151
  struct :meta_attributes do