schemaker 0.1.1 → 0.1.2
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.
- data/Gemfile +10 -6
- data/VERSION +1 -1
- data/lib/schemaker/models/base_model.rb +195 -193
- data/lib/schemaker/models/join_model.rb +29 -27
- data/lib/schemaker/models/object_model.rb +22 -20
- data/lib/schemaker/models/subject_model.rb +28 -26
- data/lib/schemaker/models.rb +2 -0
- data/lib/schemaker.rb +6 -11
- data/schemaker.gemspec +13 -19
- data/spec/models_helper.rb +0 -1
- data/spec/schemaker/model/join_spec.rb +3 -3
- data/spec/schemaker/model/object_spec.rb +4 -4
- data/spec/schemaker/model/subject_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -0
- metadata +36 -58
data/Gemfile
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
|
-
gem '
|
4
|
-
gem 'require_all', '~> 1.2.0'
|
3
|
+
gem 'sweetloader', '>= 0.1.1'
|
5
4
|
|
6
5
|
group :development, :test do
|
7
6
|
gem "activerecord", ">= 3.0.1"
|
8
7
|
gem "rspec", ">= 2.6.0"
|
8
|
+
gem 'database_cleaner', '~> 0.6.8', :git => "git://github.com/kristianmandrup/database_cleaner.git"
|
9
|
+
|
10
|
+
gem 'sqlite3'
|
11
|
+
gem 'cutter' # for inspection!
|
12
|
+
|
13
|
+
# gem 'require_all', '~> 1.2.0'
|
14
|
+
end
|
15
|
+
|
16
|
+
group :development do
|
9
17
|
gem "bundler", ">= 1"
|
10
18
|
gem "jeweler", ">= 1.6"
|
11
19
|
gem "rcov", ">= 0"
|
12
20
|
gem 'yard'
|
13
|
-
gem 'database_cleaner', '~> 0.6.8', :git => "git://github.com/kristianmandrup/database_cleaner.git"
|
14
|
-
gem 'sqlite3'
|
15
|
-
gem 'shoulda'
|
16
|
-
gem 'cutter'
|
17
21
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
@@ -6,199 +6,201 @@
|
|
6
6
|
# Each type of model to be configured shares some common functionality and state, that is encapsulated here for reuse
|
7
7
|
#
|
8
8
|
module Schemaker
|
9
|
-
class
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
class Models
|
10
|
+
class BaseModel
|
11
|
+
attr_accessor :models, :my_class
|
12
|
+
attr_reader :logs # can be used to later check which relationships were set up
|
13
|
+
|
14
|
+
# @param [Schema::Models] each model needs to have access to the collection of models it may need to create relations with
|
15
|
+
# @param [Class] each model must have a reference to the Class it aims to configure!
|
16
|
+
def initialize models, my_class
|
17
|
+
raise ArgumentError, "The first argument must be a Schema::Models instance, was #{models}" if !models.is_a?(Schemaker::Models)
|
18
|
+
raise ArgumentError, "The second argument must be the Class that is to be configured, was #{my_class}" if !my_class.is_a?(Class)
|
19
|
+
|
20
|
+
@models = models
|
21
|
+
@my_class = my_class
|
22
|
+
@logs = []
|
23
|
+
end
|
24
|
+
|
25
|
+
# The models :subject and :object must both be configured
|
26
|
+
# with a has_many relationship to the join model which the has_many :through references
|
27
|
+
def configure
|
28
|
+
create_has_many :join, class_name_option(join_class)
|
29
|
+
end
|
30
|
+
|
31
|
+
# The class name of the Class to be configured
|
32
|
+
# @return [String] class name
|
33
|
+
def clazz_name
|
34
|
+
my_class.to_s
|
35
|
+
end
|
36
|
+
alias_method :my_class_name, :clazz_name
|
37
|
+
|
38
|
+
def self.model_types
|
39
|
+
[:object, :subject, :join]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generate convenience methods for: :object, :subject, :join
|
43
|
+
# - object_model
|
44
|
+
# - object_class
|
45
|
+
# - object_class_name
|
46
|
+
|
47
|
+
model_types.each do |model_type|
|
48
|
+
class_eval %{
|
49
|
+
def #{model_type}_model
|
50
|
+
models.#{model_type}_model
|
51
|
+
end
|
52
|
+
|
53
|
+
def #{model_type}_class
|
54
|
+
models.#{model_type}_class
|
55
|
+
end
|
56
|
+
|
57
|
+
def #{model_type}_class_name
|
58
|
+
#{model_type}_class.clazz_name
|
59
|
+
end
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
# Is global logging turned on
|
66
|
+
def log_on?
|
67
|
+
Schemaker.log_on?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create a 'belongs_to' relationship on the model (Class)
|
71
|
+
# Example:
|
72
|
+
# Role.belongs_to :user, :class_name => 'User'
|
73
|
+
def create_belongs_to clazz, options = {}
|
74
|
+
make_relationship :belongs_to, clazz, options.merge(:key => singular_key(clazz))
|
75
|
+
end
|
76
|
+
|
77
|
+
# Create a 'has_many' relationship on the model (Class)
|
78
|
+
# Example:
|
79
|
+
# User.has_many :roles, :class_name => 'Role'
|
80
|
+
def create_has_many clazz, options = {}
|
81
|
+
make_relationship :has_many, clazz, options
|
82
|
+
end
|
83
|
+
|
84
|
+
# Create a 'has_many' relationship on the model (Class)
|
85
|
+
# Example:
|
86
|
+
# User.has_one :roles, :class_name => 'Role'
|
87
|
+
def create_has_one clazz, options = {}
|
88
|
+
make_relationship :has_one, clazz, options.merge(:key => singular_key(clazz))
|
89
|
+
end
|
90
|
+
|
91
|
+
# Create a 'has_many :through' relationship on the model (Class)
|
92
|
+
# Example:
|
93
|
+
# User.has_many :roles, :class_name => 'Role', :through => 'UsersRoles'
|
94
|
+
def create_has_many_through clazz, options = {}
|
95
|
+
create_has_many clazz, through_options(options)
|
96
|
+
end
|
97
|
+
|
98
|
+
# To setup symmetrical has_and_belongs_to_many relationship:
|
99
|
+
#
|
100
|
+
# Example:
|
101
|
+
#
|
102
|
+
# class UserAccount < ActiveRecord::Base
|
103
|
+
# has_and_belongs_to_many :troles, :class_name => 'Role'
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# class Role < ActiveRecord::Base
|
107
|
+
# has_and_belongs_to_many :user_accounts, :class_name => 'User'
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
def has_and_belongs_many to_clazz, options = {}
|
111
|
+
make_relationship :has_and_belongs_to_many, to_clazz, options[:from]
|
112
|
+
to_clazz.make_relationship :has_and_belongs_to_many, my_class, options[:to]
|
113
|
+
end
|
114
|
+
|
115
|
+
# Creates a given type of relationship
|
116
|
+
# @param [Symbol] the type of relationship, fx :has_many
|
117
|
+
# @param [Class, Symbol] the Class that is the object of the relationship, fx Role for a User.has_many relationship
|
118
|
+
# @param [Hash] any extra relationship options, fx for a :through relationship, or to indicate :class_name etc.
|
119
|
+
def make_relationship relationship_name, clazz, options = {}
|
120
|
+
# inspect!(binding)
|
121
|
+
key_name = (options.delete(:key) || key(clazz)).to_sym # first must be a sym too
|
122
|
+
opts_str = options.empty? ? '' : options.inspect.insert(0, ', ').gsub(/[{}]/ , '')
|
123
|
+
log "#{my_class_name}.#{relationship_name} :#{key_name}#{opts_str}" if log_on?
|
124
|
+
|
125
|
+
return my_class.send(relationship_name, key_name) if options.empty?
|
126
|
+
|
127
|
+
my_class.send(relationship_name, key_name, options)
|
128
|
+
end
|
129
|
+
|
130
|
+
# creates a key for a given type
|
131
|
+
# @param type [Symbol] - either :object, :subject or :join
|
132
|
+
def key type
|
133
|
+
models.key type
|
134
|
+
end
|
135
|
+
|
136
|
+
def get_class type
|
137
|
+
models.get_class type
|
138
|
+
end
|
139
|
+
|
140
|
+
def singular_key cls_name
|
141
|
+
model = get_class(cls_name)
|
142
|
+
model.to_s.singularize.underscore
|
143
|
+
end
|
144
|
+
|
145
|
+
def make_key cls_name
|
146
|
+
models.make_key cls_name
|
147
|
+
end
|
148
|
+
|
149
|
+
# log the relationship being added
|
150
|
+
# - to STDOUT via puts
|
151
|
+
# - to a logs list
|
152
|
+
def log msg
|
153
|
+
puts msg
|
154
|
+
logs << msg
|
155
|
+
end
|
156
|
+
|
157
|
+
# sets up the :source relationship option, typically for a has_many through relationship
|
158
|
+
def source_option cls_name
|
159
|
+
model = get_class(cls_name)
|
160
|
+
{:source => source(model) }
|
161
|
+
end
|
162
|
+
|
163
|
+
# sets up the :class_name relationship option for a given class (model
|
164
|
+
# @param [Class, String] the class to point to
|
165
|
+
def class_name_option cls_name
|
166
|
+
model = get_class(cls_name)
|
167
|
+
{:class_name => model.to_s }
|
168
|
+
end
|
169
|
+
|
170
|
+
# sets up the :through relationship option, always points to the join model
|
171
|
+
def through_option
|
172
|
+
{:through => join_model.through_key }
|
173
|
+
end
|
174
|
+
|
175
|
+
# sets up the :foreign_key relationship option
|
176
|
+
# the foreign key name should always correspond to 'my own' class name
|
177
|
+
def foreign_key_option cls_name
|
178
|
+
model = get_class(cls_name)
|
179
|
+
{:foreign_key => foreign_key(model) }
|
180
|
+
end
|
181
|
+
|
182
|
+
# sets up the full :through relationship options
|
183
|
+
# Example:
|
184
|
+
# :class_name => 'Role', :through => 'UsersRoles', :source => :role, :foreign_key => :user_id)
|
185
|
+
def through_options cls_name
|
186
|
+
model = get_class(cls_name)
|
187
|
+
through_option.merge(source_option model).merge(class_name_option model)
|
188
|
+
end
|
189
|
+
|
190
|
+
# creates the source
|
191
|
+
# Role becomes :role
|
192
|
+
def source cls_name
|
193
|
+
model = get_class(cls_name)
|
194
|
+
model.to_s.underscore.singularize.to_sym
|
195
|
+
end
|
196
|
+
|
197
|
+
# creates the foreign key
|
198
|
+
# RefManyAccount becomes :account_id
|
199
|
+
def foreign_key cls_name
|
200
|
+
model = get_class(cls_name)
|
201
|
+
name = model.to_s.underscore.split('_').last.singularize
|
202
|
+
:"#{name}_id"
|
203
|
+
end
|
22
204
|
end
|
23
|
-
|
24
|
-
# The models :subject and :object must both be configured
|
25
|
-
# with a has_many relationship to the join model which the has_many :through references
|
26
|
-
def configure
|
27
|
-
create_has_many :join, class_name_option(join_class)
|
28
|
-
end
|
29
|
-
|
30
|
-
# The class name of the Class to be configured
|
31
|
-
# @return [String] class name
|
32
|
-
def clazz_name
|
33
|
-
my_class.to_s
|
34
|
-
end
|
35
|
-
alias_method :my_class_name, :clazz_name
|
36
|
-
|
37
|
-
def self.model_types
|
38
|
-
[:object, :subject, :join]
|
39
|
-
end
|
40
|
-
|
41
|
-
# Generate convenience methods for: :object, :subject, :join
|
42
|
-
# - object_model
|
43
|
-
# - object_class
|
44
|
-
# - object_class_name
|
45
|
-
|
46
|
-
model_types.each do |model_type|
|
47
|
-
class_eval %{
|
48
|
-
def #{model_type}_model
|
49
|
-
models.#{model_type}_model
|
50
|
-
end
|
51
|
-
|
52
|
-
def #{model_type}_class
|
53
|
-
models.#{model_type}_class
|
54
|
-
end
|
55
|
-
|
56
|
-
def #{model_type}_class_name
|
57
|
-
#{model_type}_class.clazz_name
|
58
|
-
end
|
59
|
-
}
|
60
|
-
end
|
61
|
-
|
62
|
-
protected
|
63
|
-
|
64
|
-
# Is global logging turned on
|
65
|
-
def log_on?
|
66
|
-
Schemaker.log_on?
|
67
|
-
end
|
68
|
-
|
69
|
-
# Create a 'belongs_to' relationship on the model (Class)
|
70
|
-
# Example:
|
71
|
-
# Role.belongs_to :user, :class_name => 'User'
|
72
|
-
def create_belongs_to clazz, options = {}
|
73
|
-
make_relationship :belongs_to, clazz, options.merge(:key => singular_key(clazz))
|
74
|
-
end
|
75
|
-
|
76
|
-
# Create a 'has_many' relationship on the model (Class)
|
77
|
-
# Example:
|
78
|
-
# User.has_many :roles, :class_name => 'Role'
|
79
|
-
def create_has_many clazz, options = {}
|
80
|
-
make_relationship :has_many, clazz, options
|
81
|
-
end
|
82
|
-
|
83
|
-
# Create a 'has_many' relationship on the model (Class)
|
84
|
-
# Example:
|
85
|
-
# User.has_one :roles, :class_name => 'Role'
|
86
|
-
def create_has_one clazz, options = {}
|
87
|
-
make_relationship :has_one, clazz, options.merge(:key => singular_key(clazz))
|
88
|
-
end
|
89
|
-
|
90
|
-
# Create a 'has_many :through' relationship on the model (Class)
|
91
|
-
# Example:
|
92
|
-
# User.has_many :roles, :class_name => 'Role', :through => 'UsersRoles'
|
93
|
-
def create_has_many_through clazz, options = {}
|
94
|
-
create_has_many clazz, through_options(options)
|
95
|
-
end
|
96
|
-
|
97
|
-
# To setup symmetrical has_and_belongs_to_many relationship:
|
98
|
-
#
|
99
|
-
# Example:
|
100
|
-
#
|
101
|
-
# class UserAccount < ActiveRecord::Base
|
102
|
-
# has_and_belongs_to_many :troles, :class_name => 'Role'
|
103
|
-
# end
|
104
|
-
#
|
105
|
-
# class Role < ActiveRecord::Base
|
106
|
-
# has_and_belongs_to_many :user_accounts, :class_name => 'User'
|
107
|
-
# end
|
108
|
-
#
|
109
|
-
def has_and_belongs_many to_clazz, options = {}
|
110
|
-
make_relationship :has_and_belongs_to_many, to_clazz, options[:from]
|
111
|
-
to_clazz.make_relationship :has_and_belongs_to_many, my_class, options[:to]
|
112
|
-
end
|
113
|
-
|
114
|
-
# Creates a given type of relationship
|
115
|
-
# @param [Symbol] the type of relationship, fx :has_many
|
116
|
-
# @param [Class, Symbol] the Class that is the object of the relationship, fx Role for a User.has_many relationship
|
117
|
-
# @param [Hash] any extra relationship options, fx for a :through relationship, or to indicate :class_name etc.
|
118
|
-
def make_relationship relationship_name, clazz, options = {}
|
119
|
-
# inspect!(binding)
|
120
|
-
key_name = (options.delete(:key) || key(clazz)).to_sym # first must be a sym too
|
121
|
-
opts_str = options.empty? ? '' : options.inspect.insert(0, ', ').gsub(/[{}]/ , '')
|
122
|
-
log "#{my_class_name}.#{relationship_name} :#{key_name}#{opts_str}" if log_on?
|
123
|
-
|
124
|
-
return my_class.send(relationship_name, key_name) if options.empty?
|
125
|
-
|
126
|
-
my_class.send(relationship_name, key_name, options)
|
127
|
-
end
|
128
|
-
|
129
|
-
# creates a key for a given type
|
130
|
-
# @param type [Symbol] - either :object, :subject or :join
|
131
|
-
def key type
|
132
|
-
models.key type
|
133
|
-
end
|
134
|
-
|
135
|
-
def get_class type
|
136
|
-
models.get_class type
|
137
|
-
end
|
138
|
-
|
139
|
-
def singular_key cls_name
|
140
|
-
model = get_class(cls_name)
|
141
|
-
model.to_s.singularize.underscore
|
142
|
-
end
|
143
|
-
|
144
|
-
def make_key cls_name
|
145
|
-
models.make_key cls_name
|
146
|
-
end
|
147
|
-
|
148
|
-
# log the relationship being added
|
149
|
-
# - to STDOUT via puts
|
150
|
-
# - to a logs list
|
151
|
-
def log msg
|
152
|
-
puts msg
|
153
|
-
logs << msg
|
154
|
-
end
|
155
|
-
|
156
|
-
# sets up the :source relationship option, typically for a has_many through relationship
|
157
|
-
def source_option cls_name
|
158
|
-
model = get_class(cls_name)
|
159
|
-
{:source => source(model) }
|
160
|
-
end
|
161
|
-
|
162
|
-
# sets up the :class_name relationship option for a given class (model
|
163
|
-
# @param [Class, String] the class to point to
|
164
|
-
def class_name_option cls_name
|
165
|
-
model = get_class(cls_name)
|
166
|
-
{:class_name => model.to_s }
|
167
|
-
end
|
168
|
-
|
169
|
-
# sets up the :through relationship option, always points to the join model
|
170
|
-
def through_option
|
171
|
-
{:through => join_model.through_key }
|
172
|
-
end
|
173
|
-
|
174
|
-
# sets up the :foreign_key relationship option
|
175
|
-
# the foreign key name should always correspond to 'my own' class name
|
176
|
-
def foreign_key_option cls_name
|
177
|
-
model = get_class(cls_name)
|
178
|
-
{:foreign_key => foreign_key(model) }
|
179
|
-
end
|
180
|
-
|
181
|
-
# sets up the full :through relationship options
|
182
|
-
# Example:
|
183
|
-
# :class_name => 'Role', :through => 'UsersRoles', :source => :role, :foreign_key => :user_id)
|
184
|
-
def through_options cls_name
|
185
|
-
model = get_class(cls_name)
|
186
|
-
through_option.merge(source_option model).merge(class_name_option model)
|
187
|
-
end
|
188
|
-
|
189
|
-
# creates the source
|
190
|
-
# Role becomes :role
|
191
|
-
def source cls_name
|
192
|
-
model = get_class(cls_name)
|
193
|
-
model.to_s.underscore.singularize.to_sym
|
194
|
-
end
|
195
|
-
|
196
|
-
# creates the foreign key
|
197
|
-
# RefManyAccount becomes :account_id
|
198
|
-
def foreign_key cls_name
|
199
|
-
model = get_class(cls_name)
|
200
|
-
name = model.to_s.underscore.split('_').last.singularize
|
201
|
-
:"#{name}_id"
|
202
|
-
end
|
203
205
|
end
|
204
206
|
end
|
@@ -6,35 +6,37 @@
|
|
6
6
|
# Knows how to configure the Join model between a subject model (the main target of the behavior fx UserAccount) and the object model (the behavior to be added, fx Role)
|
7
7
|
#
|
8
8
|
module Schemaker
|
9
|
-
class
|
9
|
+
class Models
|
10
|
+
class JoinModel < BaseModel
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
# @param [Schema::Models] each model needs to have access to the collection of models it may need to create relations with
|
13
|
+
# @param [Class] reference to the Class it aims to configure!
|
14
|
+
def initialize models, clazz
|
15
|
+
super
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def simple_key
|
19
|
+
clazz_name.to_s.underscore
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def through_key
|
23
|
+
make_key clazz_name
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
# The join model always belongs to both the object and subject model
|
27
|
+
# the subject and object model can then each have a has_many relationship to the join model
|
28
|
+
# thus creating a Many-to-Many relationship via the join model
|
29
|
+
|
30
|
+
# Example:
|
31
|
+
# UsersRoles
|
32
|
+
# belongs_to :user, :class_name => 'UserAccount' (subject)
|
33
|
+
# belongs_to :role, :class_name => 'Role' (object)
|
34
|
+
#
|
35
|
+
# @note Do not call super here!
|
36
|
+
def configure
|
37
|
+
create_belongs_to :subject, class_name_option(:subject)
|
38
|
+
create_belongs_to :object, class_name_option(:object)
|
39
|
+
end
|
40
|
+
end
|
39
41
|
end
|
40
|
-
end
|
42
|
+
end
|
@@ -6,28 +6,30 @@
|
|
6
6
|
# Knows how to configure the relationship fro the Object model to the subject model via the Join model
|
7
7
|
#
|
8
8
|
module Schemaker
|
9
|
-
class
|
9
|
+
class Models
|
10
|
+
class ObjectModel < BaseModel
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
# @param [Schema::Models] each model needs to have access to the collection of models it may need to create relations with
|
13
|
+
# @param [Class] reference to the Class it aims to configure!
|
14
|
+
def initialize models, clazz
|
15
|
+
super
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
# Configures has_many through relationship via Join model for the object model (fx Role)
|
19
|
+
#
|
20
|
+
# Example:
|
21
|
+
# Role (object)
|
22
|
+
# has_many :accounts, :class_name => 'RefManyAccount', :through => :accounts_roles (subject)
|
23
|
+
# has_many :user_roles, :class_name => 'UserRole' (join)
|
24
|
+
def configure
|
25
|
+
super
|
26
|
+
create_has_many_through :subject
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
# @note important to use super to avoid recursive stack overflow!
|
30
|
+
def through_options options = {}
|
31
|
+
options.merge super(:subject)
|
32
|
+
end
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
@@ -6,36 +6,38 @@
|
|
6
6
|
# Knows how to configure the relationship fro the Object model to the subject model via the Join model
|
7
7
|
#
|
8
8
|
module Schemaker
|
9
|
-
class
|
9
|
+
class Models
|
10
|
+
class SubjectModel < BaseModel
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
# the main field for the behavior to add, fx :troles for adding roles behavior
|
13
|
+
attr_accessor :main_field
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
# @param [Schema::Models] each model needs to have access to the collection of models it may need to create relations with
|
16
|
+
# @param [Class] reference to the Class it aims to configure!
|
17
|
+
# @param [Symbol] the name of the main field for the behavior to add, fx :troles for adding roles behavior
|
18
|
+
def initialize models, clazz, main_field
|
19
|
+
super models, clazz
|
20
|
+
@main_field = main_field
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
# Used to set up a 'quick join' using Rails conventions and 'has_and_belongs_to_many' on the subject and object
|
24
|
+
def quick_join options = {}
|
25
|
+
create_has_and_belongs_to_many :object
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
# Example:
|
29
|
+
# UserAccount (subject)
|
30
|
+
# has_many :user_roles, :class_name => 'UserRole' (join)
|
31
|
+
# has_many :roles, :class_name => 'Role', :through => :users_roles (subject)
|
32
|
+
def configure
|
33
|
+
super
|
34
|
+
create_has_many_through :object, :key => main_field
|
35
|
+
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
# @note important to use super to avoid recursive stack overflow!
|
38
|
+
def through_options options = {}
|
39
|
+
options.merge super(:object).merge(foreign_key_option :subject)
|
40
|
+
end
|
41
|
+
end
|
40
42
|
end
|
41
43
|
end
|
data/lib/schemaker/models.rb
CHANGED
data/lib/schemaker.rb
CHANGED
@@ -1,15 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'sweetloader'
|
2
|
+
|
2
3
|
module Schemaker
|
4
|
+
autoload_modules :Models
|
5
|
+
|
3
6
|
class << self
|
4
|
-
attr_accessor :log_on
|
5
|
-
|
7
|
+
attr_accessor :log_on
|
6
8
|
alias_method :log_on?, :log_on
|
7
|
-
end
|
8
|
-
|
9
|
-
autoload :Models, 'schemaker/models'
|
10
|
-
|
11
|
-
autoload :BaseModel, 'schemaker/models/base_model'
|
12
|
-
autoload :JoinModel, 'schemaker/models/join_model'
|
13
|
-
autoload :ObjectModel, 'schemaker/models/object_model'
|
14
|
-
autoload :SubjectModel, 'schemaker/models/subject_model'
|
9
|
+
end
|
15
10
|
end
|
data/schemaker.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "schemaker"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kristian Mandrup"]
|
@@ -52,45 +52,39 @@ Gem::Specification.new do |s|
|
|
52
52
|
s.specification_version = 3
|
53
53
|
|
54
54
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
-
s.add_runtime_dependency(%q<
|
56
|
-
s.add_runtime_dependency(%q<require_all>, ["~> 1.2.0"])
|
55
|
+
s.add_runtime_dependency(%q<sweetloader>, [">= 0.1.1"])
|
57
56
|
s.add_development_dependency(%q<activerecord>, [">= 3.0.1"])
|
58
57
|
s.add_development_dependency(%q<rspec>, [">= 2.6.0"])
|
58
|
+
s.add_development_dependency(%q<database_cleaner>, ["~> 0.6.8"])
|
59
|
+
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
60
|
+
s.add_development_dependency(%q<cutter>, [">= 0"])
|
59
61
|
s.add_development_dependency(%q<bundler>, [">= 1"])
|
60
62
|
s.add_development_dependency(%q<jeweler>, [">= 1.6"])
|
61
63
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
62
64
|
s.add_development_dependency(%q<yard>, [">= 0"])
|
63
|
-
s.add_development_dependency(%q<database_cleaner>, ["~> 0.6.8"])
|
64
|
-
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
65
|
-
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
66
|
-
s.add_development_dependency(%q<cutter>, [">= 0"])
|
67
65
|
else
|
68
|
-
s.add_dependency(%q<
|
69
|
-
s.add_dependency(%q<require_all>, ["~> 1.2.0"])
|
66
|
+
s.add_dependency(%q<sweetloader>, [">= 0.1.1"])
|
70
67
|
s.add_dependency(%q<activerecord>, [">= 3.0.1"])
|
71
68
|
s.add_dependency(%q<rspec>, [">= 2.6.0"])
|
69
|
+
s.add_dependency(%q<database_cleaner>, ["~> 0.6.8"])
|
70
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
71
|
+
s.add_dependency(%q<cutter>, [">= 0"])
|
72
72
|
s.add_dependency(%q<bundler>, [">= 1"])
|
73
73
|
s.add_dependency(%q<jeweler>, [">= 1.6"])
|
74
74
|
s.add_dependency(%q<rcov>, [">= 0"])
|
75
75
|
s.add_dependency(%q<yard>, [">= 0"])
|
76
|
-
s.add_dependency(%q<database_cleaner>, ["~> 0.6.8"])
|
77
|
-
s.add_dependency(%q<sqlite3>, [">= 0"])
|
78
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
79
|
-
s.add_dependency(%q<cutter>, [">= 0"])
|
80
76
|
end
|
81
77
|
else
|
82
|
-
s.add_dependency(%q<
|
83
|
-
s.add_dependency(%q<require_all>, ["~> 1.2.0"])
|
78
|
+
s.add_dependency(%q<sweetloader>, [">= 0.1.1"])
|
84
79
|
s.add_dependency(%q<activerecord>, [">= 3.0.1"])
|
85
80
|
s.add_dependency(%q<rspec>, [">= 2.6.0"])
|
81
|
+
s.add_dependency(%q<database_cleaner>, ["~> 0.6.8"])
|
82
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
83
|
+
s.add_dependency(%q<cutter>, [">= 0"])
|
86
84
|
s.add_dependency(%q<bundler>, [">= 1"])
|
87
85
|
s.add_dependency(%q<jeweler>, [">= 1.6"])
|
88
86
|
s.add_dependency(%q<rcov>, [">= 0"])
|
89
87
|
s.add_dependency(%q<yard>, [">= 0"])
|
90
|
-
s.add_dependency(%q<database_cleaner>, ["~> 0.6.8"])
|
91
|
-
s.add_dependency(%q<sqlite3>, [">= 0"])
|
92
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
93
|
-
s.add_dependency(%q<cutter>, [">= 0"])
|
94
88
|
end
|
95
89
|
end
|
96
90
|
|
data/spec/models_helper.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'models_helper'
|
2
2
|
|
3
|
-
class UsersRoles < ActiveRecord::Base
|
3
|
+
class UsersRoles < ActiveRecord::Base
|
4
4
|
end
|
5
5
|
|
6
6
|
def join_model_class
|
7
|
-
Schemaker::JoinModel
|
7
|
+
Schemaker::Models::JoinModel
|
8
8
|
end
|
9
9
|
|
10
10
|
describe join_model_class do
|
@@ -24,4 +24,4 @@ describe join_model_class do
|
|
24
24
|
matches_all last_log, 'belongs_to :role', ':class_name=>"Role"'
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'models_helper'
|
2
2
|
|
3
3
|
def object_model_class
|
4
|
-
Schemaker::ObjectModel
|
4
|
+
Schemaker::Models::ObjectModel
|
5
5
|
end
|
6
6
|
|
7
7
|
describe object_model_class do
|
8
8
|
let(:object_model) do
|
9
9
|
object_model_class.new models, Role
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
describe '#configure' do
|
13
13
|
it 'should configure object model' do
|
14
14
|
object_model.configure
|
@@ -19,6 +19,6 @@ describe object_model_class do
|
|
19
19
|
|
20
20
|
matches_all first_log, 'has_many :user_roles', ':class_name=>"UsersRoles"'
|
21
21
|
matches_all last_log, 'Role.has_many :user_accounts', ':through=>:user_roles', ':source=>:user_account', ':class_name=>"UserAccount"'
|
22
|
-
end
|
22
|
+
end
|
23
23
|
end
|
24
|
-
end
|
24
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'models_helper'
|
2
2
|
|
3
3
|
def subject_model_class
|
4
|
-
Schemaker::SubjectModel
|
4
|
+
Schemaker::Models::SubjectModel
|
5
5
|
end
|
6
6
|
|
7
7
|
describe subject_model_class do
|
8
8
|
let(:subject_model) do
|
9
9
|
subject_model_class.new models, UserAccount, :troles
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
describe '#configure' do
|
13
13
|
it 'should configure subject model' do
|
14
14
|
subject_model.configure
|
@@ -20,6 +20,6 @@ describe subject_model_class do
|
|
20
20
|
matches_all first_log, 'has_many :user_roles', ':class_name=>"UsersRoles"'
|
21
21
|
# has_many :roles, {:through=>:user_roles, :source=>:role, :class_name=>"Role", :foreign_key=>:account_id}
|
22
22
|
matches_all last_log, 'UserAccount.has_many :troles', ':through=>:user_roles', ':source=>:role', ':class_name=>"Role"', ':foreign_key=>:account_id'
|
23
|
-
end
|
23
|
+
end
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schemaker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,30 +12,19 @@ cert_chain: []
|
|
12
12
|
date: 2011-10-12 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement: &
|
15
|
+
name: sweetloader
|
16
|
+
requirement: &2157347720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.1.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: require_all
|
27
|
-
requirement: &2165518620 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 1.2.0
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *2165518620
|
24
|
+
version_requirements: *2157347720
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: activerecord
|
38
|
-
requirement: &
|
27
|
+
requirement: &2157346060 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ! '>='
|
@@ -43,10 +32,10 @@ dependencies:
|
|
43
32
|
version: 3.0.1
|
44
33
|
type: :development
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *2157346060
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: rspec
|
49
|
-
requirement: &
|
38
|
+
requirement: &2157342600 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,32 +43,21 @@ dependencies:
|
|
54
43
|
version: 2.6.0
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: bundler
|
60
|
-
requirement: &2165517040 !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
|
-
requirements:
|
63
|
-
- - ! '>='
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version: '1'
|
66
|
-
type: :development
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: *2165517040
|
46
|
+
version_requirements: *2157342600
|
69
47
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
71
|
-
requirement: &
|
48
|
+
name: database_cleaner
|
49
|
+
requirement: &2157340920 !ruby/object:Gem::Requirement
|
72
50
|
none: false
|
73
51
|
requirements:
|
74
|
-
- -
|
52
|
+
- - ~>
|
75
53
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
54
|
+
version: 0.6.8
|
77
55
|
type: :development
|
78
56
|
prerelease: false
|
79
|
-
version_requirements: *
|
57
|
+
version_requirements: *2157340920
|
80
58
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
82
|
-
requirement: &
|
59
|
+
name: sqlite3
|
60
|
+
requirement: &2157338840 !ruby/object:Gem::Requirement
|
83
61
|
none: false
|
84
62
|
requirements:
|
85
63
|
- - ! '>='
|
@@ -87,10 +65,10 @@ dependencies:
|
|
87
65
|
version: '0'
|
88
66
|
type: :development
|
89
67
|
prerelease: false
|
90
|
-
version_requirements: *
|
68
|
+
version_requirements: *2157338840
|
91
69
|
- !ruby/object:Gem::Dependency
|
92
|
-
name:
|
93
|
-
requirement: &
|
70
|
+
name: cutter
|
71
|
+
requirement: &2157337240 !ruby/object:Gem::Requirement
|
94
72
|
none: false
|
95
73
|
requirements:
|
96
74
|
- - ! '>='
|
@@ -98,32 +76,32 @@ dependencies:
|
|
98
76
|
version: '0'
|
99
77
|
type: :development
|
100
78
|
prerelease: false
|
101
|
-
version_requirements: *
|
79
|
+
version_requirements: *2157337240
|
102
80
|
- !ruby/object:Gem::Dependency
|
103
|
-
name:
|
104
|
-
requirement: &
|
81
|
+
name: bundler
|
82
|
+
requirement: &2157336480 !ruby/object:Gem::Requirement
|
105
83
|
none: false
|
106
84
|
requirements:
|
107
|
-
- -
|
85
|
+
- - ! '>='
|
108
86
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
87
|
+
version: '1'
|
110
88
|
type: :development
|
111
89
|
prerelease: false
|
112
|
-
version_requirements: *
|
90
|
+
version_requirements: *2157336480
|
113
91
|
- !ruby/object:Gem::Dependency
|
114
|
-
name:
|
115
|
-
requirement: &
|
92
|
+
name: jeweler
|
93
|
+
requirement: &2157334900 !ruby/object:Gem::Requirement
|
116
94
|
none: false
|
117
95
|
requirements:
|
118
96
|
- - ! '>='
|
119
97
|
- !ruby/object:Gem::Version
|
120
|
-
version: '
|
98
|
+
version: '1.6'
|
121
99
|
type: :development
|
122
100
|
prerelease: false
|
123
|
-
version_requirements: *
|
101
|
+
version_requirements: *2157334900
|
124
102
|
- !ruby/object:Gem::Dependency
|
125
|
-
name:
|
126
|
-
requirement: &
|
103
|
+
name: rcov
|
104
|
+
requirement: &2157333940 !ruby/object:Gem::Requirement
|
127
105
|
none: false
|
128
106
|
requirements:
|
129
107
|
- - ! '>='
|
@@ -131,10 +109,10 @@ dependencies:
|
|
131
109
|
version: '0'
|
132
110
|
type: :development
|
133
111
|
prerelease: false
|
134
|
-
version_requirements: *
|
112
|
+
version_requirements: *2157333940
|
135
113
|
- !ruby/object:Gem::Dependency
|
136
|
-
name:
|
137
|
-
requirement: &
|
114
|
+
name: yard
|
115
|
+
requirement: &2157332720 !ruby/object:Gem::Requirement
|
138
116
|
none: false
|
139
117
|
requirements:
|
140
118
|
- - ! '>='
|
@@ -142,7 +120,7 @@ dependencies:
|
|
142
120
|
version: '0'
|
143
121
|
type: :development
|
144
122
|
prerelease: false
|
145
|
-
version_requirements: *
|
123
|
+
version_requirements: *2157332720
|
146
124
|
description: Configures relationships between subject, join and object model for a
|
147
125
|
given behavior
|
148
126
|
email: kmandrup@gmail.com
|
@@ -191,7 +169,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
169
|
version: '0'
|
192
170
|
segments:
|
193
171
|
- 0
|
194
|
-
hash:
|
172
|
+
hash: 2528253751213112279
|
195
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
174
|
none: false
|
197
175
|
requirements:
|