can_be 0.1.0 → 0.2.0
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/.travis.yml +5 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +7 -0
- data/README.md +93 -27
- data/can_be.gemspec +2 -2
- data/gemfiles/3.1.gemfile +7 -0
- data/gemfiles/3.2.gemfile +7 -0
- data/lib/can_be.rb +3 -1
- data/lib/can_be/builder.rb +7 -0
- data/lib/can_be/builder/can_be.rb +106 -0
- data/lib/can_be/builder/can_be_detail.rb +22 -0
- data/lib/can_be/config.rb +33 -0
- data/lib/can_be/model_extensions.rb +13 -1
- data/lib/can_be/processor.rb +7 -0
- data/lib/can_be/processor/instance.rb +61 -0
- data/lib/can_be/processor/klass.rb +36 -0
- data/lib/can_be/version.rb +1 -1
- data/spec/can_be/config_spec.rb +62 -0
- data/spec/can_be/model_extensions_spec.rb +391 -0
- data/spec/support/models.rb +28 -0
- data/spec/support/schema.rb +35 -0
- metadata +28 -8
- data/lib/can_be/initializer.rb +0 -90
- data/spec/can_be/model_additions_spec.rb +0 -173
data/spec/support/models.rb
CHANGED
@@ -10,3 +10,31 @@ end
|
|
10
10
|
class Person < ActiveRecord::Base
|
11
11
|
can_be :male, :female, field_name: :gender, default_type: :female
|
12
12
|
end
|
13
|
+
|
14
|
+
class Upload < ActiveRecord::Base
|
15
|
+
can_be :image_upload, :video_upload, :thumbnail_upload, :document_upload, :pdf_upload
|
16
|
+
end
|
17
|
+
|
18
|
+
class ImageUploadDetail < ActiveRecord::Base
|
19
|
+
can_be_detail :upload, :image_upload
|
20
|
+
end
|
21
|
+
|
22
|
+
class VideoUploadDetail < ActiveRecord::Base
|
23
|
+
can_be_detail :upload, :video_upload
|
24
|
+
end
|
25
|
+
|
26
|
+
class ThumbnailUploadDetail < ActiveRecord::Base
|
27
|
+
end
|
28
|
+
|
29
|
+
class DocumentUploadDetail
|
30
|
+
end
|
31
|
+
|
32
|
+
class ConfigSpecModel < ActiveRecord::Base
|
33
|
+
can_be :type1, :type2
|
34
|
+
end
|
35
|
+
|
36
|
+
class ConfigSpecDetail < ActiveRecord::Base
|
37
|
+
end
|
38
|
+
|
39
|
+
class ConfigSpecDetail2 < ActiveRecord::Base
|
40
|
+
end
|
data/spec/support/schema.rb
CHANGED
@@ -2,6 +2,7 @@ ActiveRecord::Schema.define do
|
|
2
2
|
self.verbose = false
|
3
3
|
|
4
4
|
create_table :addresses, :force => true do |t|
|
5
|
+
t.string :city
|
5
6
|
t.string :can_be_type
|
6
7
|
t.timestamps
|
7
8
|
end
|
@@ -10,4 +11,38 @@ ActiveRecord::Schema.define do
|
|
10
11
|
t.string :gender
|
11
12
|
t.timestamps
|
12
13
|
end
|
14
|
+
|
15
|
+
create_table :uploads, :force => true do |t|
|
16
|
+
t.string :can_be_type
|
17
|
+
t.integer :details_id
|
18
|
+
t.string :details_type
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :image_upload_details, :force => true do |t|
|
23
|
+
t.string :format
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
|
27
|
+
create_table :video_upload_details, :force => true do |t|
|
28
|
+
t.string :encoding
|
29
|
+
t.timestamps
|
30
|
+
end
|
31
|
+
|
32
|
+
create_table :thumbnail_upload_details, :force => true do |t|
|
33
|
+
t.timestamps
|
34
|
+
end
|
35
|
+
|
36
|
+
create_table :config_spec_models, :force => true do |t|
|
37
|
+
t.string :can_be_type
|
38
|
+
t.timestamps
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :config_spec_details, :force => true do |t|
|
42
|
+
t.timestamps
|
43
|
+
end
|
44
|
+
|
45
|
+
create_table :config_spec_details2, :force => true do |t|
|
46
|
+
t.timestamps
|
47
|
+
end
|
13
48
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: can_be
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -107,8 +107,9 @@ dependencies:
|
|
107
107
|
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '3.1'
|
110
|
-
description:
|
111
|
-
of record
|
110
|
+
description: CanBe allows you to track the type of your ActiveRecord model in a consistent
|
111
|
+
simple manner. With just a little configuration on your part, each type of record
|
112
|
+
can contain different attributes that are specifc to that type of record.
|
112
113
|
email:
|
113
114
|
- mrstarkman@gmail.com
|
114
115
|
executables: []
|
@@ -118,18 +119,29 @@ files:
|
|
118
119
|
- .gitignore
|
119
120
|
- .rspec
|
120
121
|
- .travis.yml
|
122
|
+
- .yardopts
|
123
|
+
- CHANGELOG.md
|
121
124
|
- Gemfile
|
122
125
|
- LICENSE.txt
|
123
126
|
- README.md
|
124
127
|
- Rakefile
|
125
128
|
- can_be.gemspec
|
129
|
+
- gemfiles/3.1.gemfile
|
130
|
+
- gemfiles/3.2.gemfile
|
126
131
|
- lib/can_be.rb
|
127
|
-
- lib/can_be/
|
132
|
+
- lib/can_be/builder.rb
|
133
|
+
- lib/can_be/builder/can_be.rb
|
134
|
+
- lib/can_be/builder/can_be_detail.rb
|
135
|
+
- lib/can_be/config.rb
|
128
136
|
- lib/can_be/model_extensions.rb
|
137
|
+
- lib/can_be/processor.rb
|
138
|
+
- lib/can_be/processor/instance.rb
|
139
|
+
- lib/can_be/processor/klass.rb
|
129
140
|
- lib/can_be/railtie.rb
|
130
141
|
- lib/can_be/version.rb
|
131
142
|
- log/.gitkeep
|
132
|
-
- spec/can_be/
|
143
|
+
- spec/can_be/config_spec.rb
|
144
|
+
- spec/can_be/model_extensions_spec.rb
|
133
145
|
- spec/can_be_spec.rb
|
134
146
|
- spec/spec_helper.rb
|
135
147
|
- spec/support/model_macros.rb
|
@@ -158,11 +170,19 @@ rubyforge_project:
|
|
158
170
|
rubygems_version: 1.8.23
|
159
171
|
signing_key:
|
160
172
|
specification_version: 3
|
161
|
-
summary:
|
173
|
+
summary: CanBe allows you to track the type of your ActiveRecord model in a consistent
|
174
|
+
simple manner. With just a little configuration on your part, each type of record
|
175
|
+
can contain different attributes that are specifc to that type of record. From
|
176
|
+
a data modelling perspective this is preferred over ActiveRecord STI since you will
|
177
|
+
not have many columns in your database that have null values. Under the hood, CanBe
|
178
|
+
uses one-to-one Polymorphic Associations to accomplish the different attributes
|
179
|
+
per type.
|
162
180
|
test_files:
|
163
|
-
- spec/can_be/
|
181
|
+
- spec/can_be/config_spec.rb
|
182
|
+
- spec/can_be/model_extensions_spec.rb
|
164
183
|
- spec/can_be_spec.rb
|
165
184
|
- spec/spec_helper.rb
|
166
185
|
- spec/support/model_macros.rb
|
167
186
|
- spec/support/models.rb
|
168
187
|
- spec/support/schema.rb
|
188
|
+
has_rdoc:
|
data/lib/can_be/initializer.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
module CanBe
|
2
|
-
class Initializer
|
3
|
-
def initialize(klass, types, options = {})
|
4
|
-
@klass = klass
|
5
|
-
@types = types
|
6
|
-
@options = parse_options(options)
|
7
|
-
end
|
8
|
-
|
9
|
-
def define_methods
|
10
|
-
define_instance_methods
|
11
|
-
define_class_methods
|
12
|
-
define_validations
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
def parse_options(options)
|
17
|
-
if options.nil?
|
18
|
-
default_options
|
19
|
-
else
|
20
|
-
default_options.merge(options)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def default_options
|
25
|
-
{
|
26
|
-
field_name: :can_be_type,
|
27
|
-
default_type: @types.first
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
def define_instance_methods
|
32
|
-
field_name = @options[:field_name]
|
33
|
-
|
34
|
-
@types.each do |t|
|
35
|
-
@klass.instance_eval do
|
36
|
-
define_method "#{t}?" do
|
37
|
-
send(field_name) == t
|
38
|
-
end
|
39
|
-
|
40
|
-
define_method "change_to_#{t}" do
|
41
|
-
send("#{field_name}=", t)
|
42
|
-
end
|
43
|
-
|
44
|
-
define_method "change_to_#{t}!" do
|
45
|
-
update_attributes(field_name => t)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def define_class_methods
|
52
|
-
field_name = @options[:field_name]
|
53
|
-
default_type = @options[:default_type]
|
54
|
-
|
55
|
-
@types.each do |t|
|
56
|
-
@klass.class_eval <<-EVAL
|
57
|
-
def self.create_#{t}(attributes = {}, options = {}, &block)
|
58
|
-
attributes[:#{field_name}] = '#{t}'
|
59
|
-
create(attributes, options, &block)
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.new_#{t}(attributes = {}, options = {})
|
63
|
-
attributes[:#{field_name}] = '#{t}'
|
64
|
-
new(attributes, options)
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.find_by_can_be_types(*types)
|
68
|
-
where(#{field_name}: types)
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.#{t.pluralize}
|
72
|
-
where(#{field_name}: '#{t}')
|
73
|
-
end
|
74
|
-
|
75
|
-
after_initialize do |model|
|
76
|
-
model.#{field_name} = '#{default_type}' if model.#{field_name}.nil?
|
77
|
-
end
|
78
|
-
EVAL
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def define_validations
|
83
|
-
field_name = @options[:field_name]
|
84
|
-
|
85
|
-
@klass.class_eval <<-EVAL
|
86
|
-
validates_inclusion_of :#{field_name}, in: ['#{@types.join(',').gsub(/,/, "', '")}']
|
87
|
-
EVAL
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,173 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe CanBe::ModelExtensions do
|
4
|
-
context "instance methods" do
|
5
|
-
describe "boolean record methods" do
|
6
|
-
it "are created" do
|
7
|
-
rec = new_address
|
8
|
-
rec.should respond_to :home_address?
|
9
|
-
rec.should respond_to :work_address?
|
10
|
-
end
|
11
|
-
|
12
|
-
it "responds true" do
|
13
|
-
new_address(:home_address).should be_home_address
|
14
|
-
new_address(:work_address).should be_work_address
|
15
|
-
end
|
16
|
-
|
17
|
-
it "responds false" do
|
18
|
-
new_address(:work_address).should_not be_home_address
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "change_to methods" do
|
23
|
-
it "are created" do
|
24
|
-
rec = new_address
|
25
|
-
rec.should respond_to :change_to_home_address
|
26
|
-
rec.should respond_to :change_to_work_address
|
27
|
-
end
|
28
|
-
|
29
|
-
it "updates the record" do
|
30
|
-
rec = new_address(:work_address)
|
31
|
-
rec.change_to_home_address
|
32
|
-
rec.should be_home_address
|
33
|
-
end
|
34
|
-
|
35
|
-
it "does not update the database" do
|
36
|
-
rec = create_address(:work_address)
|
37
|
-
rec.change_to_home_address
|
38
|
-
Address.first.should_not be_home_address
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "change_to! methods" do
|
43
|
-
it "are created" do
|
44
|
-
rec = create_address
|
45
|
-
rec.should respond_to :change_to_home_address!
|
46
|
-
rec.should respond_to :change_to_work_address!
|
47
|
-
end
|
48
|
-
|
49
|
-
it "updates the record" do
|
50
|
-
rec = create_address(:work_address)
|
51
|
-
rec.change_to_home_address!
|
52
|
-
rec.should be_home_address
|
53
|
-
end
|
54
|
-
|
55
|
-
it "updates the database" do
|
56
|
-
rec = create_address(:work_address)
|
57
|
-
rec.change_to_home_address!
|
58
|
-
Address.first.should be_home_address
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
context "class methods" do
|
64
|
-
describe "create methods" do
|
65
|
-
it "are created" do
|
66
|
-
Address.should respond_to :create_home_address
|
67
|
-
Address.should respond_to :create_work_address
|
68
|
-
end
|
69
|
-
|
70
|
-
it "create the records in the database" do
|
71
|
-
a = Address.create_home_address
|
72
|
-
Address.find(a.id).should be_home_address
|
73
|
-
|
74
|
-
a = Address.create_work_address
|
75
|
-
Address.find(a.id).should be_work_address
|
76
|
-
end
|
77
|
-
|
78
|
-
it "creates the records changing to the correct type" do
|
79
|
-
a = Address.create_home_address can_be_type: 'work_address'
|
80
|
-
Address.find(a.id).should be_home_address
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe "new methods" do
|
85
|
-
it "are created" do
|
86
|
-
Address.should respond_to :new_home_address
|
87
|
-
Address.should respond_to :new_work_address
|
88
|
-
end
|
89
|
-
|
90
|
-
it "create the correct type" do
|
91
|
-
Address.new_home_address.should be_home_address
|
92
|
-
Address.new_work_address.should be_work_address
|
93
|
-
end
|
94
|
-
|
95
|
-
it "create the records changing to the correct type" do
|
96
|
-
Address.create_home_address(can_be_type: 'work_address').should be_home_address
|
97
|
-
end
|
98
|
-
|
99
|
-
it "don't create the records in the database" do
|
100
|
-
Address.new_home_address
|
101
|
-
Address.new_work_address
|
102
|
-
Address.count.should == 0
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe "finder methods" do
|
107
|
-
let(:home_count) { 5 }
|
108
|
-
let(:work_count) { 4 }
|
109
|
-
let(:vacation_count) { 3 }
|
110
|
-
|
111
|
-
before :each do
|
112
|
-
home_count.times { Address.create_home_address }
|
113
|
-
work_count.times { Address.create_work_address }
|
114
|
-
vacation_count.times { Address.create_vacation_address }
|
115
|
-
end
|
116
|
-
|
117
|
-
it "are created" do
|
118
|
-
Address.should respond_to :find_by_can_be_types
|
119
|
-
Address.should respond_to 'home_address'.pluralize
|
120
|
-
Address.should respond_to 'work_address'.pluralize
|
121
|
-
end
|
122
|
-
|
123
|
-
it "#find_by_can_be_types returns the correct records" do
|
124
|
-
recs = Address.find_by_can_be_types(:home_address, :work_address)
|
125
|
-
recs.should have(home_count + work_count).items
|
126
|
-
recs.each do |a|
|
127
|
-
a.can_be_type.should =~ /^home_address|work_address$/
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
it "returns the correct records" do
|
132
|
-
recs = Address.home_addresses
|
133
|
-
recs.should have(home_count).items
|
134
|
-
recs.each { |a| a.should be_home_address }
|
135
|
-
|
136
|
-
recs = Address.work_addresses
|
137
|
-
recs.should have(work_count).items
|
138
|
-
recs.each { |a| a.should be_work_address }
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context "default type" do
|
144
|
-
it "uses the first type as the default" do
|
145
|
-
Address.new.should be_home_address
|
146
|
-
end
|
147
|
-
|
148
|
-
it "uses the specified default_type option" do
|
149
|
-
Person.new.should be_female
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
context "database field" do
|
154
|
-
it "uses the :can_be_type field (default)" do
|
155
|
-
Address.new_home_address.can_be_type.should == 'home_address'
|
156
|
-
end
|
157
|
-
|
158
|
-
it "uses the specified field" do
|
159
|
-
Person.new_female.gender.should == 'female'
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
context "validity of type value" do
|
164
|
-
it "should be valid" do
|
165
|
-
Address.new_home_address.should be_valid
|
166
|
-
Address.new_work_address.should be_valid
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should not be valid" do
|
170
|
-
Address.new(can_be_type: 'invalid type').should_not be_valid
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|