trax_model 0.0.98 → 0.0.99

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