trax_model 0.0.92 → 0.0.93
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/README.md +227 -86
- data/lib/trax.rb +0 -1
- data/lib/trax/model.rb +23 -29
- data/lib/trax/model/attributes.rb +3 -1
- data/lib/trax/model/attributes/attribute.rb +11 -0
- data/lib/trax/model/attributes/definitions.rb +16 -0
- data/lib/trax/model/attributes/errors.rb +8 -0
- data/lib/trax/model/attributes/fields.rb +74 -0
- data/lib/trax/model/attributes/mixin.rb +48 -19
- data/lib/trax/model/attributes/type.rb +4 -0
- data/lib/trax/model/attributes/types/array.rb +8 -25
- data/lib/trax/model/attributes/types/boolean.rb +51 -0
- data/lib/trax/model/attributes/types/enum.rb +53 -12
- data/lib/trax/model/attributes/types/json.rb +36 -33
- data/lib/trax/model/attributes/types/string.rb +50 -0
- data/lib/trax/model/attributes/types/uuid_array.rb +17 -28
- data/lib/trax/model/attributes/value.rb +16 -0
- data/lib/trax/model/errors.rb +7 -0
- data/lib/trax/model/mixins.rb +11 -0
- data/lib/trax/model/mixins/field_scopes.rb +60 -0
- data/lib/trax/model/mixins/id_scopes.rb +36 -0
- data/lib/trax/model/mixins/sort_by_scopes.rb +25 -0
- data/lib/trax/model/railtie.rb +1 -0
- data/lib/trax/model/scopes.rb +16 -0
- data/lib/trax/model/struct.rb +168 -14
- data/lib/trax/model/unique_id.rb +14 -21
- data/lib/trax/model/uuid.rb +1 -1
- data/lib/trax/validators/enum_attribute_validator.rb +9 -0
- data/lib/trax/validators/future_validator.rb +1 -1
- data/lib/trax/validators/json_attribute_validator.rb +3 -3
- data/lib/trax/validators/string_attribute_validator.rb +17 -0
- data/lib/trax_model/version.rb +1 -1
- data/spec/db/database.yml +16 -0
- data/spec/db/schema/default_tables.rb +68 -0
- data/spec/db/schema/pg_tables.rb +27 -0
- data/spec/spec_helper.rb +20 -3
- data/spec/support/models.rb +123 -0
- data/spec/support/pg/models.rb +103 -0
- data/spec/trax/model/attributes/fields_spec.rb +88 -0
- data/spec/trax/model/attributes/types/enum_spec.rb +51 -0
- data/spec/trax/model/attributes/types/json_spec.rb +107 -0
- data/spec/trax/model/attributes_spec.rb +13 -0
- data/spec/trax/model/errors_spec.rb +1 -2
- data/spec/trax/model/mixins/field_scopes_spec.rb +7 -0
- data/spec/trax/model/struct_spec.rb +1 -1
- data/spec/trax/model/unique_id_spec.rb +1 -3
- data/spec/trax/validators/url_validator_spec.rb +1 -1
- data/trax_model.gemspec +4 -4
- metadata +57 -19
- data/lib/trax/model/config.rb +0 -16
- data/lib/trax/model/validators.rb +0 -15
- data/lib/trax/validators/enum_validator.rb +0 -16
- data/spec/support/schema.rb +0 -151
- data/spec/trax/model/config_spec.rb +0 -13
data/lib/trax/model/unique_id.rb
CHANGED
@@ -8,17 +8,10 @@ module Trax
|
|
8
8
|
option :uuid_map, :default => {}
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
after_included do |options|
|
12
12
|
define_configuration_options!(:unique_id) do
|
13
|
+
|
13
14
|
option :uuid_prefix,
|
14
|
-
:setter => lambda{ |prefix|
|
15
|
-
if(::Trax::Model::UniqueId.config.uuid_map.values.include?(prefix) && ::Trax::Model::UniqueId.config.uuid_map[self.source.name] != prefix)
|
16
|
-
raise ::Trax::Model::Errors::DuplicatePrefixRegistered.new(:prefix => prefix, :model => self.source.name)
|
17
|
-
end
|
18
|
-
|
19
|
-
::Trax::Model::UniqueId.config.uuid_map[self.source.name] = prefix
|
20
|
-
::Trax::Model::UUIDPrefix.new(prefix)
|
21
|
-
},
|
22
15
|
:validates => {
|
23
16
|
:exclusion => {
|
24
17
|
:in => ::Trax::Model::Registry.uuid_map.values
|
@@ -31,15 +24,25 @@ module Trax
|
|
31
24
|
}
|
32
25
|
|
33
26
|
option :uuid_column, :default => ::Trax::Model::UniqueId.config.uuid_column
|
27
|
+
|
28
|
+
klass do
|
29
|
+
def uuid_prefix=(prefix)
|
30
|
+
if(::Trax::Model::UniqueId.config.uuid_map.values.include?(prefix) && ::Trax::Model::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::UniqueId.config.uuid_map[self.source.name] = prefix
|
35
|
+
super(::Trax::Model::UUIDPrefix.new(prefix))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
34
39
|
end
|
35
40
|
|
36
41
|
#grab prefix from uuid registry if uuids are defined in an initializer
|
37
42
|
if ::Trax::Model.mixin_registry.key?(:unique_id) && ::Trax::Model::UUID.klass_prefix_map.key?(self.name)
|
38
43
|
self.unique_id_config.uuid_prefix = ::Trax::Model::UUID.klass_prefix_map[self.name]
|
39
44
|
end
|
40
|
-
end
|
41
45
|
|
42
|
-
after_included do |options|
|
43
46
|
self.unique_id_config.merge!(options)
|
44
47
|
|
45
48
|
if(self.unique_id_config.uuid_prefix)
|
@@ -76,16 +79,6 @@ module Trax
|
|
76
79
|
self.unique_id_config.uuid_prefix
|
77
80
|
end
|
78
81
|
end
|
79
|
-
|
80
|
-
# def self.apply_mixin(target, options)
|
81
|
-
# target.unique_id_config.merge!(options)
|
82
|
-
#
|
83
|
-
# if(target.unique_id_config.uuid_prefix)
|
84
|
-
# target.default_value_for(:"#{target.unique_id_config.uuid_column}") {
|
85
|
-
# ::Trax::Model::UUID.generate(target.unique_id_config.uuid_prefix)
|
86
|
-
# }
|
87
|
-
# end
|
88
|
-
# end
|
89
82
|
end
|
90
83
|
end
|
91
84
|
end
|
data/lib/trax/model/uuid.rb
CHANGED
@@ -28,7 +28,7 @@ module Trax
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def record
|
31
|
-
@record ||= record_type ? record_type.find_by(:"#{record_type.uuid_column}" => self) : nil
|
31
|
+
@record ||= record_type ? record_type.find_by(:"#{record_type.unique_id_config.uuid_column}" => self) : nil
|
32
32
|
end
|
33
33
|
|
34
34
|
def record_type
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class EnumAttributeValidator < ActiveModel::EachValidator
|
2
|
+
def validate_each(object, attribute, value)
|
3
|
+
enum_attribute = object.class.fields_module[attribute]
|
4
|
+
|
5
|
+
unless value.is_a?(enum_attribute) && enum_attribute === value
|
6
|
+
object.errors[attribute] = "#{value} is not an allowed value"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class FutureValidator < ActiveModel::EachValidator
|
2
2
|
def validate_each(object, attribute, value)
|
3
|
-
object.errors[attribute] << 'Must be in future' if value < ::DateTime.now
|
3
|
+
object.errors[attribute] << 'Must be in future' if value && (value < ::DateTime.now)
|
4
4
|
end
|
5
5
|
end
|
@@ -3,13 +3,13 @@
|
|
3
3
|
# that a hash is not provided
|
4
4
|
class JsonAttributeValidator < ActiveModel::EachValidator
|
5
5
|
def validate_each(object, attribute, value)
|
6
|
-
json_attribute = object.class.
|
6
|
+
json_attribute = object.class.fields_module[attribute]
|
7
7
|
|
8
8
|
unless value.is_a?(json_attribute) && value.valid?
|
9
9
|
if value.is_a?(json_attribute)
|
10
10
|
value.errors.messages.each_pair do |k,v|
|
11
|
-
v
|
12
|
-
object.errors.add(
|
11
|
+
v.flatten.join(", ") if v.is_a?(Array)
|
12
|
+
object.errors.add("#{attribute}.#{k}", v)
|
13
13
|
end
|
14
14
|
else
|
15
15
|
object.errors[attribute] << "can not be blank"
|
@@ -0,0 +1,17 @@
|
|
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 StringAttributeValidator < ActiveModel::EachValidator
|
5
|
+
def validate_each(object, attribute, value)
|
6
|
+
string_attribute = value.class
|
7
|
+
|
8
|
+
unless value.valid?
|
9
|
+
if value.is_a?(string_attribute)
|
10
|
+
value.errors.messages.each_pair do |k,v|
|
11
|
+
v.flatten.join(", ") if v.is_a?(Array)
|
12
|
+
object.errors.add("#{attribute}.#{k}", v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/trax_model/version.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
default: &default
|
2
|
+
adapter: sqlite3
|
3
|
+
database: spec/test.db
|
4
|
+
|
5
|
+
sqllite:
|
6
|
+
<<: *default
|
7
|
+
|
8
|
+
postgres:
|
9
|
+
<<: *default
|
10
|
+
adapter: postgresql
|
11
|
+
encoding: unicode
|
12
|
+
database: trax_model_tests
|
13
|
+
pool: 5
|
14
|
+
host: localhost
|
15
|
+
username: postgres
|
16
|
+
password:
|
@@ -0,0 +1,68 @@
|
|
1
|
+
DEFAULT_TABLES = Proc.new do
|
2
|
+
create_table "products", :force => true do |t|
|
3
|
+
t.string "name"
|
4
|
+
t.integer "category_id"
|
5
|
+
t.integer "user_id"
|
6
|
+
t.decimal "price"
|
7
|
+
t.integer "in_stock_quantity"
|
8
|
+
t.integer "on_order_quantity"
|
9
|
+
t.boolean "active"
|
10
|
+
t.string "uuid"
|
11
|
+
t.integer "status"
|
12
|
+
t.integer "size"
|
13
|
+
t.datetime "created_at", :null => false
|
14
|
+
t.datetime "updated_at", :null => false
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table "messages", :force => true do |t|
|
18
|
+
t.string "title"
|
19
|
+
t.text "body"
|
20
|
+
t.integer "status"
|
21
|
+
t.string "uuid"
|
22
|
+
t.boolean "deleted"
|
23
|
+
t.datetime "deleted_at"
|
24
|
+
t.datetime "deliver_at"
|
25
|
+
t.datetime "created_at", :null => false
|
26
|
+
t.datetime "updated_at", :null => false
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table "widgets", :force => true do |t|
|
30
|
+
t.string "uuid"
|
31
|
+
t.string "email_address"
|
32
|
+
t.string "subdomain"
|
33
|
+
t.string "website"
|
34
|
+
t.integer "status"
|
35
|
+
t.datetime "created_at", :null => false
|
36
|
+
t.datetime "updated_at", :null => false
|
37
|
+
end
|
38
|
+
|
39
|
+
create_table "things", :force => true do |t|
|
40
|
+
t.string "name"
|
41
|
+
t.string "uuid"
|
42
|
+
t.datetime "created_at", :null => false
|
43
|
+
t.datetime "updated_at", :null => false
|
44
|
+
end
|
45
|
+
|
46
|
+
create_table "people", :force => true do |t|
|
47
|
+
t.string "name"
|
48
|
+
t.string "uuid"
|
49
|
+
t.datetime "created_at", :null => false
|
50
|
+
t.datetime "updated_at", :null => false
|
51
|
+
end
|
52
|
+
|
53
|
+
create_table "staplers", :force => true do |t|
|
54
|
+
t.string "name"
|
55
|
+
t.string "type"
|
56
|
+
t.integer "attribute_set_id"
|
57
|
+
t.datetime "created_at", :null => false
|
58
|
+
t.datetime "updated_at", :null => false
|
59
|
+
end
|
60
|
+
|
61
|
+
create_table "swingline_stapler_attribute_sets", :force => true do |t|
|
62
|
+
t.float "speed"
|
63
|
+
t.string "owner"
|
64
|
+
|
65
|
+
t.datetime "created_at", :null => false
|
66
|
+
t.datetime "updated_at", :null => false
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
PG_TABLES = Proc.new do
|
2
|
+
execute %q{CREATE EXTENSION IF NOT EXISTS "uuid-ossp";}
|
3
|
+
execute %q{CREATE EXTENSION IF NOT EXISTS "pg_trgm";}
|
4
|
+
|
5
|
+
create_table "ecommerce_products", :id => :uuid, :force => true do |t|
|
6
|
+
t.string "name"
|
7
|
+
t.string "type"
|
8
|
+
t.uuid "category_id"
|
9
|
+
t.uuid "user_id"
|
10
|
+
t.decimal "price"
|
11
|
+
t.boolean "active"
|
12
|
+
t.integer "status"
|
13
|
+
t.jsonb "custom_fields"
|
14
|
+
t.jsonb "stock"
|
15
|
+
t.datetime "created_at", :null => false
|
16
|
+
t.datetime "updated_at", :null => false
|
17
|
+
end
|
18
|
+
|
19
|
+
create_table "ecommerce_product_attribute_sets", :id => :uuid, :force => true do |t|
|
20
|
+
t.uuid "user_id"
|
21
|
+
t.uuid "product_id"
|
22
|
+
t.string "type"
|
23
|
+
t.jsonb "specifics"
|
24
|
+
t.datetime "created_at", :null => false
|
25
|
+
t.datetime "updated_at", :null => false
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,35 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler'
|
3
3
|
require 'simplecov'
|
4
|
-
require 'pry'
|
4
|
+
# require 'pry'
|
5
5
|
require 'trax_model'
|
6
|
+
require 'active_record'
|
6
7
|
|
7
8
|
SimpleCov.start do
|
8
9
|
add_filter '/spec/'
|
9
10
|
end
|
10
11
|
|
12
|
+
ENV["DB"] ||= "sqllite"
|
13
|
+
ENV["DB"] = "postgres" if ENV["DB"] == "pg" || ENV["pg"] == "true"
|
14
|
+
|
11
15
|
RSpec.configure do |config|
|
16
|
+
config.filter_run_excluding :postgres => true unless ENV["DB"] == "postgres"
|
17
|
+
|
12
18
|
config.before(:suite) do
|
19
|
+
db_config = ::YAML::load(::File.open("#{File.dirname(__FILE__)}/db/database.yml"))
|
20
|
+
|
21
|
+
::ActiveRecord::Base.establish_connection(db_config[ENV["DB"]])
|
22
|
+
|
23
|
+
::ActiveRecord::Base.connection.tables.each do |table|
|
24
|
+
::ActiveRecord::Base.connection.drop_table(table)
|
25
|
+
end
|
26
|
+
|
27
|
+
::Trax::Model.configure do |config|
|
28
|
+
config.auto_include = false
|
29
|
+
end
|
30
|
+
|
31
|
+
::Dir["#{::File.dirname(__FILE__)}/support/*.rb"].each { |f| require f }
|
13
32
|
end
|
14
33
|
end
|
15
34
|
|
16
35
|
Bundler.require(:default, :development, :test)
|
17
|
-
|
18
|
-
::Dir["#{::File.dirname(__FILE__)}/support/*.rb"].each {|f| require f }
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
::ActiveRecord::Schema.define(:version => 1) do
|
4
|
+
require_relative '../db/schema/default_tables'
|
5
|
+
instance_eval(&DEFAULT_TABLES)
|
6
|
+
|
7
|
+
if ENV["DB"] == "postgres"
|
8
|
+
require_relative '../db/schema/pg_tables'
|
9
|
+
instance_eval(&PG_TABLES)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
if ENV["DB"] == "postgres"
|
14
|
+
require_relative 'pg/models'
|
15
|
+
end
|
16
|
+
|
17
|
+
class Product < ::ActiveRecord::Base
|
18
|
+
include ::Trax::Model
|
19
|
+
include ::Trax::Model::Attributes::Mixin
|
20
|
+
|
21
|
+
mixins :unique_id => {
|
22
|
+
:uuid_column => "uuid",
|
23
|
+
:uuid_prefix => "1a"
|
24
|
+
}
|
25
|
+
|
26
|
+
define_attributes do
|
27
|
+
enum :status, :default => :in_stock do
|
28
|
+
define :in_stock, 1
|
29
|
+
define :out_of_stock, 2
|
30
|
+
define :backordered, 3
|
31
|
+
end
|
32
|
+
|
33
|
+
boolean :active, :default => false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Products
|
38
|
+
class Shoes < Product
|
39
|
+
include ::Trax::Model
|
40
|
+
include ::Trax::Model::Attributes::Mixin
|
41
|
+
end
|
42
|
+
|
43
|
+
class MensShoes < Shoes
|
44
|
+
include ::Trax::Model
|
45
|
+
include ::Trax::Model::Attributes::Mixin
|
46
|
+
|
47
|
+
define_attributes do
|
48
|
+
enum :size, :default => :mens_9 do
|
49
|
+
define :mens_6, 1
|
50
|
+
define :mens_7, 2
|
51
|
+
define :mens_8, 3
|
52
|
+
define :mens_9, 4
|
53
|
+
define :mens_10, 5
|
54
|
+
define :mens_11, 6
|
55
|
+
define :mens_12, 7
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Widget < ::ActiveRecord::Base
|
62
|
+
include ::Trax::Model
|
63
|
+
|
64
|
+
mixins :unique_id => {
|
65
|
+
:uuid_column => "uuid",
|
66
|
+
:uuid_prefix => "2a"
|
67
|
+
}
|
68
|
+
|
69
|
+
validates :subdomain, :subdomain => true, :allow_nil => true
|
70
|
+
validates :email_address, :email => true, :allow_nil => true
|
71
|
+
validates :website, :url => true, :allow_nil => true
|
72
|
+
end
|
73
|
+
|
74
|
+
class Message < ::ActiveRecord::Base
|
75
|
+
include ::Trax::Model
|
76
|
+
|
77
|
+
mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "3a" },
|
78
|
+
:freezable => true,
|
79
|
+
:restorable => { :field => :deleted }
|
80
|
+
|
81
|
+
enum :status => [ :queued, :scheduled, :delivered, :failed_delivery ]
|
82
|
+
|
83
|
+
default_value_for :status do
|
84
|
+
self.statuses[:queued]
|
85
|
+
end
|
86
|
+
|
87
|
+
validates :deliver_at, :future => true, :allow_nil => true
|
88
|
+
|
89
|
+
freezable_by_enum :status => [ :delivered, :failed_delivery ]
|
90
|
+
end
|
91
|
+
|
92
|
+
class Thing < ::ActiveRecord::Base
|
93
|
+
include ::Trax::Model
|
94
|
+
|
95
|
+
mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "4a" }
|
96
|
+
end
|
97
|
+
|
98
|
+
class Person < ::ActiveRecord::Base
|
99
|
+
include ::Trax::Model
|
100
|
+
|
101
|
+
mixins :unique_id => { :uuid_column => "uuid", :uuid_prefix => "5a" }
|
102
|
+
end
|
103
|
+
|
104
|
+
class Stapler < ::ActiveRecord::Base
|
105
|
+
include ::Trax::Model
|
106
|
+
end
|
107
|
+
|
108
|
+
class SwinglineStapler < ::Stapler
|
109
|
+
include ::Trax::Model::STI::Attributes
|
110
|
+
end
|
111
|
+
|
112
|
+
class SwinglineStaplerAttributeSet < ::ActiveRecord::Base
|
113
|
+
end
|
114
|
+
|
115
|
+
require 'trax/model/struct'
|
116
|
+
|
117
|
+
class StoreCategory < ::Trax::Model::Struct
|
118
|
+
string :name
|
119
|
+
struct :meta_attributes do
|
120
|
+
string :description
|
121
|
+
string :keywords
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Ecommerce
|
2
|
+
class ProductAttributeSet < ::ActiveRecord::Base
|
3
|
+
self.table_name = "ecommerce_product_attribute_sets"
|
4
|
+
|
5
|
+
include ::Trax::Model
|
6
|
+
include ::Trax::Model::Attributes::Mixin
|
7
|
+
|
8
|
+
mixins :unique_id => { :uuid_prefix => "c2" }
|
9
|
+
|
10
|
+
belongs_to :user, :class_name => "Ecommerce::User"
|
11
|
+
belongs_to :product, :class_name => "Ecommerce::Product"
|
12
|
+
end
|
13
|
+
|
14
|
+
class ShippingAttributes < ::Ecommerce::ProductAttributeSet
|
15
|
+
include ::Trax::Model
|
16
|
+
include ::Trax::Model::Attributes::Mixin
|
17
|
+
|
18
|
+
define_attributes do
|
19
|
+
struct :specifics, :validate => true do
|
20
|
+
string :cost, :default => 0
|
21
|
+
|
22
|
+
validates(:cost, :length => {:minimum => 10})
|
23
|
+
|
24
|
+
enum :service do
|
25
|
+
define :usps, 1
|
26
|
+
define :fedex, 2
|
27
|
+
end
|
28
|
+
|
29
|
+
struct :dimensions, :validate => true do
|
30
|
+
string :length
|
31
|
+
string :width
|
32
|
+
string :height
|
33
|
+
|
34
|
+
validates(:length, :length => {:maximum => 10})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Product < ::ActiveRecord::Base
|
41
|
+
self.table_name = "ecommerce_products"
|
42
|
+
|
43
|
+
include ::Trax::Model
|
44
|
+
include ::Trax::Model::Attributes::Mixin
|
45
|
+
|
46
|
+
mixins :unique_id => { :uuid_prefix => "9a" }
|
47
|
+
|
48
|
+
belongs_to :store, :class_name => "Ecommerce::Store"
|
49
|
+
|
50
|
+
define_attributes do
|
51
|
+
string :name, :default => "Whatever" do
|
52
|
+
validates(self, :length => { :minimum => 20 })
|
53
|
+
end
|
54
|
+
boolean :active, :default => true
|
55
|
+
|
56
|
+
enum :status, :default => :in_stock do
|
57
|
+
define :in_stock, 1
|
58
|
+
define :out_of_stock, 2
|
59
|
+
define :backordered, 3
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module Products
|
65
|
+
class Shoes < ::Ecommerce::Product
|
66
|
+
include ::Trax::Model
|
67
|
+
include ::Trax::Model::Attributes::Mixin
|
68
|
+
end
|
69
|
+
|
70
|
+
class MensShoes < ::Ecommerce::Products::Shoes
|
71
|
+
include ::Trax::Model
|
72
|
+
include ::Trax::Model::Attributes::Mixin
|
73
|
+
|
74
|
+
define_attributes do
|
75
|
+
string :name, :default => "Some Shoe Name", :define_scopes => true
|
76
|
+
boolean :active, :default => true, :define_scopes => true
|
77
|
+
|
78
|
+
struct :custom_fields do
|
79
|
+
string :primary_utility, :default => "Skateboarding", :define_scopes => true
|
80
|
+
string :sole_material
|
81
|
+
boolean :has_shoelaces, :define_scopes => true
|
82
|
+
|
83
|
+
enum :color, :default => :blue, :define_scopes => false do
|
84
|
+
define :red, 1
|
85
|
+
define :blue, 2
|
86
|
+
define :green, 3
|
87
|
+
define :black, 4
|
88
|
+
end
|
89
|
+
|
90
|
+
enum :size, :default => :mens_9, :define_scopes => true do
|
91
|
+
define :mens_6, 1
|
92
|
+
define :mens_7, 2
|
93
|
+
define :mens_8, 3
|
94
|
+
define :mens_9, 4
|
95
|
+
define :mens_10, 5
|
96
|
+
define :mens_11, 6
|
97
|
+
define :mens_12, 7
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|