trax_model 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +47 -0
- data/lib/trax/model/enum.rb +23 -11
- data/lib/trax/model/errors.rb +6 -0
- data/lib/trax/model/freezable.rb +1 -3
- data/lib/trax/model/mixin.rb +13 -0
- data/lib/trax/model/mti/abstract.rb +4 -1
- data/lib/trax/model/restorable.rb +52 -0
- data/lib/trax/model/sti/attributes.rb +94 -0
- data/lib/trax/model/sti.rb +9 -0
- data/lib/trax/model/unique_id.rb +1 -1
- data/lib/trax/model.rb +48 -0
- data/lib/trax_model/version.rb +1 -1
- data/spec/support/schema.rb +33 -2
- data/spec/trax/model/restorable_spec.rb +44 -0
- data/spec/trax/model/sti/attributes_spec.rb +15 -0
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b684425923dcaa1272ed04a98ab652ecf61c56ca
|
4
|
+
data.tar.gz: 5c66900bde83b806346c7784ed378ed92ff0c50f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee0a7829a4bfe0098f47a5f2e8e8da1e6dd54abb10fc129f1addef047108a0f359396fe3a27b37bc7155c734667d9bc5ee68265af85adcefd96859108d8eb871
|
7
|
+
data.tar.gz: 0283a5f7de147bd1a5d51c38e925c3935696f2ea00ecc390e3735d249e48b92e7d3628fb6489c3483b7c0fdfe38ed95de64b83a00a28277b0c8b7c68e60c67f4
|
data/README.md
CHANGED
@@ -163,6 +163,53 @@ The main disadvantages are:
|
|
163
163
|
1. No shared view between child types. I.E. thats what the MTI entity is for. (want to find all blog posts? You cant unless you select a type first, or are using this gem, or a postgres view or something else)
|
164
164
|
2. More difficult to setup since each child table needs its own table.
|
165
165
|
|
166
|
+
# STI
|
167
|
+
|
168
|
+
Trax also has a specialized blend of STI, where you place the union of attributes in the parent table, but for the child specific attributes, you create one separate table per subclass, i.e. given the following pseudo schema
|
169
|
+
``` ruby
|
170
|
+
#(Note this may make more sense to be a has_one rather than a belongs_to, cant remember why I set it up that way)
|
171
|
+
|
172
|
+
Post
|
173
|
+
:type => string, :title => String, :attribute_set_id => (integer or uuid, this is required ATM.)
|
174
|
+
|
175
|
+
VideoPost
|
176
|
+
video_url => string
|
177
|
+
video_thumbnail => binary
|
178
|
+
|
179
|
+
TextPost
|
180
|
+
body => text
|
181
|
+
```
|
182
|
+
You would have 2 additional models
|
183
|
+
|
184
|
+
1. VideoPostAttributeSet
|
185
|
+
2. TextPostAttributeSet
|
186
|
+
|
187
|
+
Which contain the type specific columns.
|
188
|
+
|
189
|
+
Then you just need to include
|
190
|
+
|
191
|
+
``` ruby
|
192
|
+
class VideoPost < Post
|
193
|
+
include ::Trax::Model::STI::Attributes
|
194
|
+
|
195
|
+
sti_attribute :video_url, :video_thumbnail
|
196
|
+
end
|
197
|
+
```
|
198
|
+
|
199
|
+
STI Attribute will set up the delegation to the attribute_set model, so now you can do
|
200
|
+
|
201
|
+
``` ruby
|
202
|
+
VideoPost.new(:video_url => "http://whatever.com")
|
203
|
+
```
|
204
|
+
|
205
|
+
ETC..
|
206
|
+
|
207
|
+
AttributeSet model will be built automatically if it does not exist, and delegated to accordingly.
|
208
|
+
|
209
|
+
The idea is to hide the complexity of dealing with the attribute_set table, and do as much as possible in the main model, as its really just an extension of itself.
|
210
|
+
|
211
|
+
If you need to override one of the attribute_sets methods, try super! as that will delegate to it and call super on the attribute set model.
|
212
|
+
|
166
213
|
|
167
214
|
## Installation
|
168
215
|
|
data/lib/trax/model/enum.rb
CHANGED
@@ -20,18 +20,10 @@
|
|
20
20
|
module Trax
|
21
21
|
module Model
|
22
22
|
module Enum
|
23
|
-
|
23
|
+
include ::Trax::Model::Mixin
|
24
24
|
|
25
25
|
module ClassMethods
|
26
|
-
def
|
27
|
-
options.assert_valid_keys(:prefix, :source, :message)
|
28
|
-
options[:message] ||= "Is not a valid value for #{enum_name}"
|
29
|
-
options[:prefix] ||= true
|
30
|
-
options[:source] ||= enum_name
|
31
|
-
enum_values = args.is_a?(Hash) ? args.keys : args
|
32
|
-
validation_options = { :in => enum_values, :message => options.extract!(:message) }
|
33
|
-
|
34
|
-
self.validates_inclusion_of(enum_name, validation_options)
|
26
|
+
def define_scopes_for_trax_enum(enum_name)
|
35
27
|
scope_method_name = :"by_#{enum_name}"
|
36
28
|
scope_not_method_name = :"by_#{enum_name}_not"
|
37
29
|
|
@@ -43,8 +35,28 @@ module Trax
|
|
43
35
|
enum_hash = self.__send__("#{enum_name}".pluralize).hash
|
44
36
|
where.not(enum_name => enum_hash.with_indifferent_access.slice(*values.flatten.compact.uniq).values)
|
45
37
|
}
|
38
|
+
end
|
39
|
+
|
40
|
+
#todo: ew need to clean this up
|
41
|
+
def as_enum(enum_name, enum_mapping, options = {})
|
42
|
+
enum_values = enum_mapping.is_a?(Hash) ? enum_mapping.keys : enum_mapping
|
43
|
+
options.assert_valid_keys(:prefix, :source, :message, :default, :validate)
|
44
|
+
|
45
|
+
options[:message] ||= "Invalid value selected for #{enum_name}"
|
46
|
+
options[:prefix] ||= true
|
47
|
+
options[:source] ||= enum_name
|
48
|
+
default_value = options.extract!(:default)[:default] if options.key?(:default)
|
49
|
+
|
50
|
+
validation_options = { :in => enum_values, :message => options.extract!(:message)[:message] }
|
51
|
+
|
52
|
+
self.validates_inclusion_of(enum_name, validation_options) unless options.key?(:validate) && !options[:validate]
|
53
|
+
options.delete(:validate) if options.key?(:validate)
|
54
|
+
|
55
|
+
define_scopes_for_trax_enum(enum_name)
|
56
|
+
|
57
|
+
self.default_value_for(enum_name) { default_value } if default_value
|
46
58
|
|
47
|
-
super(enum_name,
|
59
|
+
super(enum_name, enum_mapping, options)
|
48
60
|
end
|
49
61
|
end
|
50
62
|
end
|
data/lib/trax/model/errors.rb
CHANGED
data/lib/trax/model/freezable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Trax
|
2
2
|
module Model
|
3
3
|
module Freezable
|
4
|
-
|
4
|
+
include ::Trax::Model::Mixin
|
5
5
|
|
6
6
|
included do
|
7
7
|
class_attribute :freezable_fields
|
@@ -11,7 +11,6 @@ module Trax
|
|
11
11
|
module ClassMethods
|
12
12
|
def freezable_by_enum(options = {})
|
13
13
|
freezable_fields.merge!(options)
|
14
|
-
|
15
14
|
define_frozen_validators_for_enum(options)
|
16
15
|
end
|
17
16
|
|
@@ -26,6 +25,5 @@ module Trax
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
31
29
|
end
|
@@ -8,7 +8,9 @@ module Trax
|
|
8
8
|
class_attribute :mti_config
|
9
9
|
|
10
10
|
self.abstract_class = true
|
11
|
-
self.mti_config = ::
|
11
|
+
self.mti_config = ::ActiveSupport::HashWithIndifferentAccess.new({
|
12
|
+
:foreign_key => :id
|
13
|
+
})
|
12
14
|
|
13
15
|
scope :records, lambda{
|
14
16
|
map(&:entity)
|
@@ -50,6 +52,7 @@ module Trax
|
|
50
52
|
|
51
53
|
def entity_model(options)
|
52
54
|
valid_options = options.assert_valid_keys(:class_name, :foreign_key)
|
55
|
+
|
53
56
|
mti_config.merge!(valid_options)
|
54
57
|
|
55
58
|
self.has_one(:entity, mti_config.symbolize_keys)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Trax
|
2
|
+
module Model
|
3
|
+
module Restorable
|
4
|
+
include ::Trax::Model::Mixin
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :_restorable_config
|
8
|
+
|
9
|
+
alias_method :destroy!, :destroy
|
10
|
+
|
11
|
+
self._restorable_config = {
|
12
|
+
:field => :is_deleted,
|
13
|
+
:timestamp_field => :deleted_at,
|
14
|
+
:hide_deleted => true
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def setup_restorable!
|
20
|
+
self.class_eval do
|
21
|
+
if(self._restorable_config[:hide_deleted])
|
22
|
+
default_scope { by_not_deleted }
|
23
|
+
end
|
24
|
+
|
25
|
+
### Clear default deleted scope ###
|
26
|
+
scope :by_is_deleted, lambda { |*|
|
27
|
+
unscope(:where => self._restorable_config[:field]).where(self._restorable_config[:field] => true)
|
28
|
+
}
|
29
|
+
scope :by_not_deleted, lambda { |*|
|
30
|
+
where(self._restorable_config[:field] => false)
|
31
|
+
}
|
32
|
+
|
33
|
+
default_value_for(self._restorable_config[:field]) { false }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
self.update_attributes(self._restorable_config[:field] => true, self._restorable_config[:timestamp_field] => ::DateTime.now)
|
40
|
+
end
|
41
|
+
|
42
|
+
def restore
|
43
|
+
self.update_attributes(self._restorable_config[:field] => false, self._restorable_config[:timestamp_field] => ::DateTime.now)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.apply_mixin(target, options)
|
47
|
+
target._restorable_config.merge!(options)
|
48
|
+
target.setup_restorable!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Trax
|
2
|
+
module Model
|
3
|
+
module STI
|
4
|
+
module Attributes
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
#not configurable atm as you can see below
|
8
|
+
|
9
|
+
included do
|
10
|
+
class_attribute :_attribute_set_column,
|
11
|
+
:_attribute_set_class_name,
|
12
|
+
:_attribute_set_relation_name,
|
13
|
+
:_sti_attributes
|
14
|
+
|
15
|
+
self._sti_attributes = []
|
16
|
+
|
17
|
+
self._attribute_set_relation_name = :attribute_set
|
18
|
+
self._attribute_set_column = :attribute_set_id
|
19
|
+
self._attribute_set_class_name = "#{name}AttributeSet"
|
20
|
+
|
21
|
+
self.belongs_to(self._attribute_set_relation_name, :class_name => self._attribute_set_class_name, :validate => true)
|
22
|
+
self.validates(self._attribute_set_relation_name, :presence => true)
|
23
|
+
|
24
|
+
self.before_create(:attribute_set)
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes
|
28
|
+
super.merge!(sti_attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def attribute_set
|
32
|
+
build_attribute_set if super.nil?
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def sti_attributes
|
38
|
+
sti_attribute_hash = self.class._sti_attributes.inject({}) do |result, attribute|
|
39
|
+
result["#{attribute}"] = __send__(attribute)
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
sti_attribute_hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def super!(*args)
|
47
|
+
method_caller = caller_locations(1,1)[0].label
|
48
|
+
attribute_set.send(method_caller, *args)
|
49
|
+
end
|
50
|
+
|
51
|
+
module ClassMethods
|
52
|
+
def sti_attribute(*args)
|
53
|
+
options = args.extract_options!
|
54
|
+
|
55
|
+
args.each do |attribute_name|
|
56
|
+
return unless self._attribute_set_class_name.constantize.table_exists?
|
57
|
+
raise ::Trax::Model::Errors::STIAttributeNotFound unless self._attribute_set_class_name.constantize.column_names.include?("#{attribute_name}")
|
58
|
+
|
59
|
+
self._sti_attributes << attribute_name
|
60
|
+
|
61
|
+
self.delegate(attribute_name, :to => :attribute_set)
|
62
|
+
self.delegate("#{attribute_name}=", :to => :attribute_set) unless options.key?(:writer) && options[:writer] == false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def validates_uniqueness_of!(*args)
|
67
|
+
options = args.extract_options!
|
68
|
+
|
69
|
+
args.each do |arg|
|
70
|
+
validation_method_name = :"validate_#{arg.to_s}"
|
71
|
+
|
72
|
+
self.send(:define_method, :"validate_#{arg.to_s}") do |*_args|
|
73
|
+
where_scope_hash = {}
|
74
|
+
field_value = self.__send__(arg)
|
75
|
+
where_scope_hash[arg] = field_value
|
76
|
+
|
77
|
+
where_scope = self._attribute_set_class_name.constantize.where(where_scope_hash).all
|
78
|
+
|
79
|
+
options[:scope].each do |field|
|
80
|
+
scoped_field_value = self.__send__(field)
|
81
|
+
where_scope.merge(self.class.where({field => scoped_field_value}))
|
82
|
+
end if options.has_key?(:scope)
|
83
|
+
|
84
|
+
errors.add(arg, "has already been taken") if where_scope.limit(1).any?
|
85
|
+
end
|
86
|
+
|
87
|
+
self.validate(validation_method_name)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/trax/model/unique_id.rb
CHANGED
data/lib/trax/model.rb
CHANGED
@@ -4,6 +4,7 @@ require 'hashie/dash'
|
|
4
4
|
require 'hashie/mash'
|
5
5
|
require 'simple_enum'
|
6
6
|
require_relative './string'
|
7
|
+
# require_relative './enum'
|
7
8
|
require_relative './validators/email_validator'
|
8
9
|
require_relative './validators/frozen_validator'
|
9
10
|
require_relative './validators/future_validator'
|
@@ -24,12 +25,35 @@ module Trax
|
|
24
25
|
autoload :UUIDPrefix
|
25
26
|
autoload :UniqueId
|
26
27
|
autoload :Matchable
|
28
|
+
autoload :Mixin
|
27
29
|
autoload :MTI
|
30
|
+
autoload :Restorable
|
31
|
+
autoload :STI
|
28
32
|
autoload :Validators
|
29
33
|
|
30
34
|
include ::Trax::Model::Matchable
|
31
35
|
include ::ActiveModel::Dirty
|
32
36
|
|
37
|
+
class << self
|
38
|
+
attr_accessor :mixin_registry
|
39
|
+
end
|
40
|
+
|
41
|
+
@mixin_registry = {}
|
42
|
+
|
43
|
+
def self.register_mixin(mixin_klass)
|
44
|
+
mixin_key = mixin_klass.name.demodulize.underscore.to_sym
|
45
|
+
mixin_registry[mixin_key] = mixin_klass
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.eager_autoload_mixins!
|
49
|
+
::Trax::Model::Enum
|
50
|
+
::Trax::Model::Freezable
|
51
|
+
::Trax::Model::Restorable
|
52
|
+
::Trax::Model::UniqueId
|
53
|
+
end
|
54
|
+
|
55
|
+
eager_autoload_mixins!
|
56
|
+
|
33
57
|
included do
|
34
58
|
class_attribute :trax_defaults
|
35
59
|
|
@@ -48,6 +72,30 @@ module Trax
|
|
48
72
|
end
|
49
73
|
end
|
50
74
|
|
75
|
+
def mixin(key, options = {})
|
76
|
+
mixin_klass = ::Trax::Model.mixin_registry[key]
|
77
|
+
|
78
|
+
self.class_eval do
|
79
|
+
include(mixin_klass) unless self.ancestors.include?(mixin_klass)
|
80
|
+
|
81
|
+
if(options.is_a?(Hash) && !options.blank?)
|
82
|
+
mixin_klass.apply_mixin(self, options) if mixin_klass.respond_to?(:apply_mixin)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def mixins(*args)
|
88
|
+
options = args.extract_options!
|
89
|
+
|
90
|
+
if(!options.blank?)
|
91
|
+
options.each_pair do |key, val|
|
92
|
+
self.mixin(key, val)
|
93
|
+
end
|
94
|
+
else
|
95
|
+
args.map{ |key| mixin(key) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
51
99
|
def register_trax_models(*models)
|
52
100
|
models.each do |model|
|
53
101
|
register_trax_model(model)
|
data/lib/trax_model/version.rb
CHANGED
data/spec/support/schema.rb
CHANGED
@@ -28,6 +28,8 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
28
28
|
t.text "body"
|
29
29
|
t.integer "status"
|
30
30
|
t.string "uuid"
|
31
|
+
t.boolean "deleted"
|
32
|
+
t.datetime "deleted_at"
|
31
33
|
t.datetime "deliver_at"
|
32
34
|
t.datetime "created_at", :null => false
|
33
35
|
t.datetime "updated_at", :null => false
|
@@ -55,6 +57,22 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
55
57
|
t.datetime "created_at", :null => false
|
56
58
|
t.datetime "updated_at", :null => false
|
57
59
|
end
|
60
|
+
|
61
|
+
create_table "staplers", :force => true do |t|
|
62
|
+
t.string "name"
|
63
|
+
t.string "type"
|
64
|
+
t.integer "attribute_set_id"
|
65
|
+
t.datetime "created_at", :null => false
|
66
|
+
t.datetime "updated_at", :null => false
|
67
|
+
end
|
68
|
+
|
69
|
+
create_table "swingline_stapler_attribute_sets", :force => true do |t|
|
70
|
+
t.float "speed"
|
71
|
+
t.string "owner"
|
72
|
+
|
73
|
+
t.datetime "created_at", :null => false
|
74
|
+
t.datetime "updated_at", :null => false
|
75
|
+
end
|
58
76
|
end
|
59
77
|
|
60
78
|
class Product < ::ActiveRecord::Base
|
@@ -76,10 +94,12 @@ end
|
|
76
94
|
|
77
95
|
class Message < ::ActiveRecord::Base
|
78
96
|
include ::Trax::Model
|
79
|
-
include ::Trax::Model::Freezable
|
80
97
|
|
81
98
|
defaults :uuid_prefix => "3a", :uuid_column => "uuid"
|
82
99
|
|
100
|
+
mixins :freezable => true,
|
101
|
+
:restorable => { :field => :deleted }
|
102
|
+
|
83
103
|
enum :status => [:queued, :scheduled, :delivered, :failed_delivery]
|
84
104
|
|
85
105
|
default_value_for :status do
|
@@ -88,7 +108,7 @@ class Message < ::ActiveRecord::Base
|
|
88
108
|
|
89
109
|
validates :deliver_at, :future => true, :allow_nil => true
|
90
110
|
|
91
|
-
freezable_by_enum :status => [:delivered, :failed_delivery]
|
111
|
+
freezable_by_enum :status => [ :delivered, :failed_delivery ]
|
92
112
|
end
|
93
113
|
|
94
114
|
class Thing < ::ActiveRecord::Base
|
@@ -102,3 +122,14 @@ class Person < ::ActiveRecord::Base
|
|
102
122
|
|
103
123
|
defaults :uuid_column => "uuid"
|
104
124
|
end
|
125
|
+
|
126
|
+
class Stapler < ::ActiveRecord::Base
|
127
|
+
include ::Trax::Model
|
128
|
+
end
|
129
|
+
|
130
|
+
class SwinglineStapler < ::Stapler
|
131
|
+
include ::Trax::Model::STI::Attributes
|
132
|
+
end
|
133
|
+
|
134
|
+
class SwinglineStaplerAttributeSet < ::ActiveRecord::Base
|
135
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Trax::Model::Restorable do
|
4
|
+
subject{ ::Message.create(:title => "Whatever") }
|
5
|
+
|
6
|
+
its(:deleted) { should be false }
|
7
|
+
|
8
|
+
context "when destroyed" do
|
9
|
+
it "should soft delete" do
|
10
|
+
subject.destroy
|
11
|
+
subject.deleted.should be true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be restorable" do
|
15
|
+
subject.destroy
|
16
|
+
subject.restore
|
17
|
+
subject.deleted.should be false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "scopes" do
|
22
|
+
subject{ ::Message.create(:title => "My Message") }
|
23
|
+
|
24
|
+
context ".default_scope" do
|
25
|
+
it { Message.all.where_values_hash["deleted"].should eq false }
|
26
|
+
|
27
|
+
it do
|
28
|
+
subject
|
29
|
+
Message.all.pluck(:id).should include(subject.id)
|
30
|
+
end
|
31
|
+
|
32
|
+
it do
|
33
|
+
subject.destroy
|
34
|
+
Message.all.pluck(:id).should_not include(subject.id)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it ".by_is_deleted" do
|
39
|
+
subject.destroy
|
40
|
+
binding.pry
|
41
|
+
Message.by_is_deleted.pluck(:id).should include(subject.id)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Trax::Model::STI::Attributes do
|
4
|
+
|
5
|
+
before do
|
6
|
+
SwinglineStapler.sti_attribute(:owner)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "delegation" do
|
10
|
+
subject{ ::SwinglineStapler.new(:owner => "Milton Waddums") }
|
11
|
+
|
12
|
+
its(:owner) { should eq "Milton Waddums" }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
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.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Ayre
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trax_core
|
@@ -284,11 +284,15 @@ files:
|
|
284
284
|
- lib/trax/model/errors.rb
|
285
285
|
- lib/trax/model/freezable.rb
|
286
286
|
- lib/trax/model/matchable.rb
|
287
|
+
- lib/trax/model/mixin.rb
|
287
288
|
- lib/trax/model/mti.rb
|
288
289
|
- lib/trax/model/mti/abstract.rb
|
289
290
|
- lib/trax/model/mti/entity.rb
|
290
291
|
- lib/trax/model/mti/namespace.rb
|
291
292
|
- lib/trax/model/registry.rb
|
293
|
+
- lib/trax/model/restorable.rb
|
294
|
+
- lib/trax/model/sti.rb
|
295
|
+
- lib/trax/model/sti/attributes.rb
|
292
296
|
- lib/trax/model/unique_id.rb
|
293
297
|
- lib/trax/model/uuid.rb
|
294
298
|
- lib/trax/model/uuid_prefix.rb
|
@@ -308,6 +312,8 @@ files:
|
|
308
312
|
- spec/trax/model/freezable_spec.rb
|
309
313
|
- spec/trax/model/matchable_spec.rb
|
310
314
|
- spec/trax/model/registry_spec.rb
|
315
|
+
- spec/trax/model/restorable_spec.rb
|
316
|
+
- spec/trax/model/sti/attributes_spec.rb
|
311
317
|
- spec/trax/model/unique_id_spec.rb
|
312
318
|
- spec/trax/model/uuid_prefix_spec.rb
|
313
319
|
- spec/trax/model/uuid_spec.rb
|
@@ -338,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
338
344
|
version: '0'
|
339
345
|
requirements: []
|
340
346
|
rubyforge_project:
|
341
|
-
rubygems_version: 2.
|
347
|
+
rubygems_version: 2.4.5
|
342
348
|
signing_key:
|
343
349
|
specification_version: 4
|
344
350
|
summary: Higher level ActiveRecord models for rails
|
@@ -350,6 +356,8 @@ test_files:
|
|
350
356
|
- spec/trax/model/freezable_spec.rb
|
351
357
|
- spec/trax/model/matchable_spec.rb
|
352
358
|
- spec/trax/model/registry_spec.rb
|
359
|
+
- spec/trax/model/restorable_spec.rb
|
360
|
+
- spec/trax/model/sti/attributes_spec.rb
|
353
361
|
- spec/trax/model/unique_id_spec.rb
|
354
362
|
- spec/trax/model/uuid_prefix_spec.rb
|
355
363
|
- spec/trax/model/uuid_spec.rb
|