dbview_cti 0.0.3 → 0.1.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/CHANGELOG.md +7 -0
- data/README.md +41 -2
- data/lib/db_view_cti/model/cti.rb +63 -1
- data/lib/db_view_cti/model/extensions.rb +1 -0
- data/lib/db_view_cti/schema_dumper.rb +6 -2
- data/lib/db_view_cti/version.rb +1 -1
- data/spec/dummy-rails-3/app/models/astronaut.rb +5 -0
- data/spec/dummy-rails-3/app/models/captain.rb +5 -0
- data/spec/dummy-rails-3/app/models/experiment.rb +6 -0
- data/spec/dummy-rails-3/app/models/experiment_space_ship_performance.rb +6 -0
- data/spec/dummy-rails-3/app/models/launch.rb +5 -0
- data/spec/dummy-rails-3/app/models/space_ship.rb +6 -0
- data/spec/dummy-rails-3/db/migrate/20131021211442_create_launches.rb +12 -0
- data/spec/dummy-rails-3/db/migrate/20131022010731_create_captains.rb +12 -0
- data/spec/dummy-rails-3/db/migrate/20131022020536_create_astronauts.rb +9 -0
- data/spec/dummy-rails-3/db/migrate/20131022020655_create_habtm_join_table.rb +11 -0
- data/spec/dummy-rails-3/db/migrate/20131022030659_create_experiments.rb +9 -0
- data/spec/dummy-rails-3/db/migrate/20131022030720_create_experiment_space_ship_performances.rb +14 -0
- data/spec/dummy-rails-3/db/schema.rb +129 -0
- data/spec/dummy-rails-4/db/schema.rb +112 -0
- data/spec/models/space_shuttle_spec.rb +100 -0
- metadata +18 -4
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -4,7 +4,8 @@
|
|
4
4
|
This gem implements [Class Table Inheritance](http://martinfowler.com/eaaCatalog/classTableInheritance.html) (CTI)
|
5
5
|
for Rails, as an alternative to Single Table Inheritance (STI). The implementation is based on database views.
|
6
6
|
|
7
|
-
Currently, only PostgreSQL (version >= 9.1) is supported. The gem works for both Rails 3.2 and Rails 4 apps
|
7
|
+
Currently, only PostgreSQL (version >= 9.1) is supported. The gem works for both Rails 3.2 and Rails 4 apps, and on
|
8
|
+
MRI (>= 1.9.3), Rubinius and JRuby in 1.9 mode (due to some issues JRuby is not included in the travis tests, though).
|
8
9
|
|
9
10
|
## Installation
|
10
11
|
|
@@ -142,6 +143,41 @@ After running `rake db:migrate` we can now use our new models, e.g. in the rails
|
|
142
143
|
|
143
144
|
Note that Car has all attributes of the vehicles, motor_vehicles and cars tables combined. When saving, the attributes are stored in their corresponding tables.
|
144
145
|
|
146
|
+
## Initializer
|
147
|
+
|
148
|
+
When running the migrations and for some of the functionality (see e.g. the `convert_to` and `specialize` methods below),
|
149
|
+
it is important that each class knows about the full class hierarchy. This is taken care of automatically when a class
|
150
|
+
is loaded. However, in order to have full class hierarchy information all classes in the hierarchy have to be loaded,
|
151
|
+
which is not necessarily the case since rails lazy-loads classes (e.g. in development mode).
|
152
|
+
Therefore, we have to force loading of all classes by referencing the leaf-classes in the hierarchy in an initializer.
|
153
|
+
|
154
|
+
For the example given above the leaf classes are Car and MotorCycle, so we put the following in an initializer (e.g. in
|
155
|
+
`config/initializers/dbview_cti.rb`):
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
# Force loading of all classes in the CTI hierachy by referencing the leaf classes here
|
159
|
+
Car
|
160
|
+
MotorCycle
|
161
|
+
```
|
162
|
+
|
163
|
+
In development mode, Rails reloads files as you modify them. If a file in the class hierarchy is modified, all classes
|
164
|
+
have to be reloaded, otherwise methods such as `specialize` and `convert_to` (see below) will no longer work correctly.
|
165
|
+
To make sure the whole hierarchy is reloaded at every request (in development) we can modify the above initializer to:
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
# this block makes rails reload the code after each request in development mode
|
169
|
+
Rails.configuration.to_prepare do
|
170
|
+
# Force loading of all classes in the CTI hierachy by referencing the leaf classes here
|
171
|
+
Car
|
172
|
+
MotorCycle
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
## Associations
|
177
|
+
|
178
|
+
Associations (`has_many`, `has_one`, etc.) work and are inherited as you would expect. The only caveat is that
|
179
|
+
in Rails 4 it might be necessary to explicitly specify the join table when using `has_and_belongs_to_many`.
|
180
|
+
|
145
181
|
## API
|
146
182
|
|
147
183
|
### Models
|
@@ -211,8 +247,11 @@ The `change` syntax is not (yet?) supported for recreating database views.
|
|
211
247
|
|
212
248
|
## Notes
|
213
249
|
|
214
|
-
* Using dbview_cti doesn't interfere with foreign key constraints. In fact, I recommend adding foreign key constraints
|
250
|
+
* Using dbview_cti doesn't interfere with foreign key constraints. In fact, I highly recommend adding foreign key constraints
|
215
251
|
between the tables in a CTI hierarchy (e.g. using [foreigner](https://github.com/matthuhiggins/foreigner)).
|
252
|
+
* When creating foreign key constraints involving tables that are part of the hierarchy, always refer to the tables
|
253
|
+
themselves, not the views. When modifying the models in future migrations, the views may need to be recreated, which
|
254
|
+
would cause problems with the foreign key constraints.
|
216
255
|
* Take care when using database id's. Since the data for a Car object is spread over several tables,
|
217
256
|
the id of a Car instance will generally be different than the id of the MotorVehicle instance you get when you
|
218
257
|
convert the Car instance to a MotorVehicle.
|
@@ -112,7 +112,62 @@ module DBViewCTI
|
|
112
112
|
@cti_descendants ||= {}
|
113
113
|
@cti_descendants.each(&block)
|
114
114
|
result
|
115
|
-
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# redefine association class methods (except for belongs_to)
|
118
|
+
[:has_many, :has_and_belongs_to_many, :has_one].each do |name|
|
119
|
+
self.class_eval <<-eos, __FILE__, __LINE__+1
|
120
|
+
def #{name}(*args)
|
121
|
+
cti_initialize_cti_associations
|
122
|
+
@cti_associations[:#{name}] << args.first
|
123
|
+
super
|
124
|
+
end
|
125
|
+
eos
|
126
|
+
end
|
127
|
+
|
128
|
+
# redefine associations defined in ascendant classes so they keep working
|
129
|
+
def cti_redefine_associations
|
130
|
+
@cti_ascendants.each do |ascendant|
|
131
|
+
[:has_many, :has_and_belongs_to_many].each do |association_type|
|
132
|
+
ascendant.constantize.cti_associations[association_type].each do |association|
|
133
|
+
cti_redefine_to_many(ascendant, association)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
ascendant.constantize.cti_associations[:has_one].each do |association|
|
137
|
+
cti_redefine_has_one(ascendant, association)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# redefine has_many and has_and_belongs_to_many association
|
143
|
+
def cti_redefine_to_many(class_name, association)
|
144
|
+
plural = association.to_s
|
145
|
+
singular = association.to_s.singularize
|
146
|
+
[ plural, "#{plural}=", "#{singular}_ids", "#{singular}_ids=" ].each do |name|
|
147
|
+
cti_redefine_single_association(name, class_name)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# redefine has_many and has_and_belongs_to_many association
|
152
|
+
def cti_redefine_has_one(class_name, association)
|
153
|
+
singular = association
|
154
|
+
[ association, "#{association}=", "build_#{association}", "create_#{association}", "create_#{association}!" ].each do |name|
|
155
|
+
cti_redefine_single_association(name, class_name)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def cti_redefine_single_association(name, class_name)
|
160
|
+
self.class_eval <<-eos, __FILE__, __LINE__+1
|
161
|
+
def #{name}(*args)
|
162
|
+
self.convert_to('#{class_name}').send('#{name}', *args)
|
163
|
+
end
|
164
|
+
eos
|
165
|
+
end
|
166
|
+
|
167
|
+
def cti_associations
|
168
|
+
cti_initialize_cti_associations
|
169
|
+
@cti_associations
|
170
|
+
end
|
116
171
|
|
117
172
|
include DBViewCTI::SQLGeneration::Model
|
118
173
|
|
@@ -123,6 +178,13 @@ module DBViewCTI
|
|
123
178
|
result[0]['count'].to_i
|
124
179
|
end
|
125
180
|
|
181
|
+
def cti_initialize_cti_associations
|
182
|
+
@cti_associations ||= {}
|
183
|
+
[:has_many, :has_and_belongs_to_many, :has_one].each do |name|
|
184
|
+
@cti_associations[name] ||= []
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
126
188
|
end
|
127
189
|
end
|
128
190
|
end
|
@@ -13,8 +13,12 @@ module DBViewCTI
|
|
13
13
|
base_classes = []
|
14
14
|
@connection.tables.sort.each do |table|
|
15
15
|
next if ignore_table?(table)
|
16
|
-
|
17
|
-
|
16
|
+
begin
|
17
|
+
klass = DBViewCTI::Names.table_to_class_name(table).constantize
|
18
|
+
base_classes << klass if klass.respond_to?('cti_base_class?') && klass.cti_base_class?
|
19
|
+
rescue NameError
|
20
|
+
# do nothing
|
21
|
+
end
|
18
22
|
end
|
19
23
|
base_classes.each do |klass|
|
20
24
|
dump_cti_hierarchy(klass, stream)
|
data/lib/db_view_cti/version.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
class SpaceShip < Vehicle
|
2
2
|
attr_accessible :single_use, :reliability unless Rails::VERSION::MAJOR > 3
|
3
3
|
cti_derived_class
|
4
|
+
|
5
|
+
has_many :launches
|
6
|
+
has_one :captain
|
7
|
+
has_and_belongs_to_many :astronauts, :join_table => 'astronauts_space_ships'
|
8
|
+
has_many :experiment_space_ship_performances
|
9
|
+
has_many :experiments, :through => :experiment_space_ship_performances
|
4
10
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateHabtmJoinTable < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :astronauts_space_ships, id: false do |t|
|
4
|
+
t.integer :astronaut_id
|
5
|
+
t.integer :space_ship_id
|
6
|
+
end
|
7
|
+
|
8
|
+
add_foreign_key(:astronauts_space_ships, :astronauts)
|
9
|
+
add_foreign_key(:astronauts_space_ships, :space_ships)
|
10
|
+
end
|
11
|
+
end
|
data/spec/dummy-rails-3/db/migrate/20131022030720_create_experiment_space_ship_performances.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateExperimentSpaceShipPerformances < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :experiment_space_ship_performances do |t|
|
4
|
+
t.references :experiment
|
5
|
+
t.references :space_ship
|
6
|
+
t.date :performed_at
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_foreign_key(:experiment_space_ship_performances, :experiments)
|
12
|
+
add_foreign_key(:experiment_space_ship_performances, :space_ships)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended to check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(:version => 20131022030720) do
|
15
|
+
|
16
|
+
create_table "astronauts", :force => true do |t|
|
17
|
+
t.string "name"
|
18
|
+
t.datetime "created_at", :null => false
|
19
|
+
t.datetime "updated_at", :null => false
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table "astronauts_space_ships", :id => false, :force => true do |t|
|
23
|
+
t.integer "astronaut_id"
|
24
|
+
t.integer "space_ship_id"
|
25
|
+
end
|
26
|
+
|
27
|
+
create_table "captains", :force => true do |t|
|
28
|
+
t.integer "space_ship_id"
|
29
|
+
t.string "name"
|
30
|
+
t.datetime "created_at", :null => false
|
31
|
+
t.datetime "updated_at", :null => false
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table "cars", :force => true do |t|
|
35
|
+
t.integer "motor_vehicle_id"
|
36
|
+
t.boolean "stick_shift"
|
37
|
+
t.boolean "convertible"
|
38
|
+
t.datetime "created_at", :null => false
|
39
|
+
t.datetime "updated_at", :null => false
|
40
|
+
end
|
41
|
+
|
42
|
+
create_table "experiment_space_ship_performances", :force => true do |t|
|
43
|
+
t.integer "experiment_id"
|
44
|
+
t.integer "space_ship_id"
|
45
|
+
t.date "performed_at"
|
46
|
+
t.datetime "created_at", :null => false
|
47
|
+
t.datetime "updated_at", :null => false
|
48
|
+
end
|
49
|
+
|
50
|
+
create_table "experiments", :force => true do |t|
|
51
|
+
t.string "name"
|
52
|
+
t.datetime "created_at", :null => false
|
53
|
+
t.datetime "updated_at", :null => false
|
54
|
+
end
|
55
|
+
|
56
|
+
create_table "launches", :force => true do |t|
|
57
|
+
t.integer "space_ship_id"
|
58
|
+
t.date "date"
|
59
|
+
t.datetime "created_at", :null => false
|
60
|
+
t.datetime "updated_at", :null => false
|
61
|
+
end
|
62
|
+
|
63
|
+
create_table "motor_cycles", :force => true do |t|
|
64
|
+
t.integer "motor_vehicle_id"
|
65
|
+
t.boolean "offroad"
|
66
|
+
t.datetime "created_at", :null => false
|
67
|
+
t.datetime "updated_at", :null => false
|
68
|
+
end
|
69
|
+
|
70
|
+
create_table "motor_vehicles", :force => true do |t|
|
71
|
+
t.integer "vehicle_id"
|
72
|
+
t.string "fuel"
|
73
|
+
t.integer "number_of_wheels"
|
74
|
+
t.datetime "created_at", :null => false
|
75
|
+
t.datetime "updated_at", :null => false
|
76
|
+
end
|
77
|
+
|
78
|
+
create_table "rocket_engines", :force => true do |t|
|
79
|
+
t.integer "space_ship_id"
|
80
|
+
t.string "name"
|
81
|
+
t.datetime "created_at", :null => false
|
82
|
+
t.datetime "updated_at", :null => false
|
83
|
+
end
|
84
|
+
|
85
|
+
create_table "space_ships", :force => true do |t|
|
86
|
+
t.integer "vehicle_id"
|
87
|
+
t.boolean "single_use"
|
88
|
+
t.datetime "created_at", :null => false
|
89
|
+
t.datetime "updated_at", :null => false
|
90
|
+
t.integer "reliability"
|
91
|
+
end
|
92
|
+
|
93
|
+
create_table "space_shuttles", :force => true do |t|
|
94
|
+
t.integer "space_ship_id"
|
95
|
+
t.integer "power"
|
96
|
+
t.datetime "created_at", :null => false
|
97
|
+
t.datetime "updated_at", :null => false
|
98
|
+
end
|
99
|
+
|
100
|
+
create_table "vehicles", :force => true do |t|
|
101
|
+
t.string "name"
|
102
|
+
t.integer "mass"
|
103
|
+
t.datetime "created_at", :null => false
|
104
|
+
t.datetime "updated_at", :null => false
|
105
|
+
end
|
106
|
+
|
107
|
+
cti_create_view('MotorVehicle')
|
108
|
+
cti_create_view('Car')
|
109
|
+
cti_create_view('MotorCycle')
|
110
|
+
cti_create_view('SpaceShip')
|
111
|
+
cti_create_view('SpaceShuttle')
|
112
|
+
|
113
|
+
add_foreign_key "astronauts_space_ships", "astronauts", :name => "astronauts_space_ships_astronaut_id_fk"
|
114
|
+
add_foreign_key "astronauts_space_ships", "space_ships", :name => "astronauts_space_ships_space_ship_id_fk"
|
115
|
+
|
116
|
+
add_foreign_key "captains", "space_ships", :name => "captains_space_ship_id_fk"
|
117
|
+
|
118
|
+
add_foreign_key "experiment_space_ship_performances", "experiments", :name => "experiment_space_ship_performances_experiment_id_fk"
|
119
|
+
add_foreign_key "experiment_space_ship_performances", "space_ships", :name => "experiment_space_ship_performances_space_ship_id_fk"
|
120
|
+
|
121
|
+
add_foreign_key "launches", "space_ships", :name => "launches_space_ship_id_fk"
|
122
|
+
|
123
|
+
add_foreign_key "rocket_engines", "space_ships", :name => "rocket_engines_space_ship_id_fk"
|
124
|
+
|
125
|
+
add_foreign_key "space_ships", "vehicles", :name => "space_ships_vehicle_id_fk"
|
126
|
+
|
127
|
+
add_foreign_key "space_shuttles", "space_ships", :name => "space_shuttles_space_ship_id_fk"
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(version: 20131022020655) do
|
15
|
+
|
16
|
+
create_table "astronauts", force: true do |t|
|
17
|
+
t.string "name"
|
18
|
+
t.datetime "created_at"
|
19
|
+
t.datetime "updated_at"
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table "astronauts_space_ships", id: false, force: true do |t|
|
23
|
+
t.integer "astronaut_id"
|
24
|
+
t.integer "space_ship_id"
|
25
|
+
end
|
26
|
+
|
27
|
+
create_table "captains", force: true do |t|
|
28
|
+
t.integer "space_ship_id"
|
29
|
+
t.string "name"
|
30
|
+
t.datetime "created_at"
|
31
|
+
t.datetime "updated_at"
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table "cars", force: true do |t|
|
35
|
+
t.integer "motor_vehicle_id"
|
36
|
+
t.boolean "stick_shift"
|
37
|
+
t.boolean "convertible"
|
38
|
+
t.datetime "created_at"
|
39
|
+
t.datetime "updated_at"
|
40
|
+
end
|
41
|
+
|
42
|
+
create_table "launches", force: true do |t|
|
43
|
+
t.integer "space_ship_id"
|
44
|
+
t.date "date"
|
45
|
+
t.datetime "created_at"
|
46
|
+
t.datetime "updated_at"
|
47
|
+
end
|
48
|
+
|
49
|
+
create_table "motor_cycles", force: true do |t|
|
50
|
+
t.integer "motor_vehicle_id"
|
51
|
+
t.boolean "offroad"
|
52
|
+
t.datetime "created_at"
|
53
|
+
t.datetime "updated_at"
|
54
|
+
end
|
55
|
+
|
56
|
+
create_table "motor_vehicles", force: true do |t|
|
57
|
+
t.integer "vehicle_id"
|
58
|
+
t.string "fuel"
|
59
|
+
t.integer "number_of_wheels"
|
60
|
+
t.datetime "created_at"
|
61
|
+
t.datetime "updated_at"
|
62
|
+
end
|
63
|
+
|
64
|
+
create_table "rocket_engines", force: true do |t|
|
65
|
+
t.integer "space_ship_id"
|
66
|
+
t.string "name"
|
67
|
+
t.datetime "created_at"
|
68
|
+
t.datetime "updated_at"
|
69
|
+
end
|
70
|
+
|
71
|
+
create_table "space_ships", force: true do |t|
|
72
|
+
t.integer "vehicle_id"
|
73
|
+
t.boolean "single_use"
|
74
|
+
t.datetime "created_at"
|
75
|
+
t.datetime "updated_at"
|
76
|
+
t.integer "reliability"
|
77
|
+
end
|
78
|
+
|
79
|
+
create_table "space_shuttles", force: true do |t|
|
80
|
+
t.integer "space_ship_id"
|
81
|
+
t.integer "power"
|
82
|
+
t.datetime "created_at"
|
83
|
+
t.datetime "updated_at"
|
84
|
+
end
|
85
|
+
|
86
|
+
create_table "vehicles", force: true do |t|
|
87
|
+
t.string "name"
|
88
|
+
t.integer "mass"
|
89
|
+
t.datetime "created_at"
|
90
|
+
t.datetime "updated_at"
|
91
|
+
end
|
92
|
+
|
93
|
+
cti_create_view('MotorVehicle')
|
94
|
+
cti_create_view('Car')
|
95
|
+
cti_create_view('MotorCycle')
|
96
|
+
cti_create_view('SpaceShip')
|
97
|
+
cti_create_view('SpaceShuttle')
|
98
|
+
|
99
|
+
add_foreign_key "astronauts_space_ships", "astronauts", :name => "astronauts_space_ships_astronaut_id_fk"
|
100
|
+
add_foreign_key "astronauts_space_ships", "space_ships", :name => "astronauts_space_ships_space_ship_id_fk"
|
101
|
+
|
102
|
+
add_foreign_key "captains", "space_ships", :name => "captains_space_ship_id_fk"
|
103
|
+
|
104
|
+
add_foreign_key "launches", "space_ships", :name => "launches_space_ship_id_fk"
|
105
|
+
|
106
|
+
add_foreign_key "rocket_engines", "space_ships", :name => "rocket_engines_space_ship_id_fk"
|
107
|
+
|
108
|
+
add_foreign_key "space_ships", "vehicles", :name => "space_ships_vehicle_id_fk"
|
109
|
+
|
110
|
+
add_foreign_key "space_shuttles", "space_ships", :name => "space_shuttles_space_ship_id_fk"
|
111
|
+
|
112
|
+
end
|
@@ -19,4 +19,104 @@ describe SpaceShuttle do
|
|
19
19
|
shuttle.convert_to(:space_ship).reliability.should eq 100
|
20
20
|
end
|
21
21
|
|
22
|
+
it "can use has_many associations defined in ascendant classes" do
|
23
|
+
# create dummy space ships to make sure the shuttle we'll cereate has a different database id than
|
24
|
+
# its associated spaceship
|
25
|
+
(1..2).map { SpaceShip.create }
|
26
|
+
shuttle = SpaceShuttle.create(:name => 'Discovery', :reliability => 100)
|
27
|
+
shuttle.id.should_not eq shuttle.convert_to(:space_ship).id
|
28
|
+
# test has_many functionality
|
29
|
+
launch1 = Launch.new(:date => Date.today)
|
30
|
+
launch2 = Launch.new(:date => Date.tomorrow)
|
31
|
+
launch3 = Launch.new(:date => Date.tomorrow)
|
32
|
+
expect {
|
33
|
+
shuttle.launches << launch1
|
34
|
+
shuttle.save!
|
35
|
+
}.to change(Launch, :count).by(1)
|
36
|
+
expect {
|
37
|
+
shuttle.launches = [ launch1, launch2 ]
|
38
|
+
shuttle.save!
|
39
|
+
}.to change(Launch, :count).by(1)
|
40
|
+
shuttle.launch_ids.sort.should eq [ launch1.id, launch2.id ]
|
41
|
+
launch3.save!
|
42
|
+
shuttle.launch_ids = [ launch1.id, launch3.id ]
|
43
|
+
shuttle.launch_ids.sort.should eq [ launch1.id, launch3.id ]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can use has_many :through associations defined in ascendant classes" do
|
47
|
+
# create dummy space ships to make sure the shuttle we'll cereate has a different database id than
|
48
|
+
# its associated spaceship
|
49
|
+
(1..2).map { SpaceShip.create }
|
50
|
+
shuttle = SpaceShuttle.create(:name => 'Discovery', :reliability => 100)
|
51
|
+
shuttle.id.should_not eq shuttle.convert_to(:space_ship).id
|
52
|
+
# test has_many functionality
|
53
|
+
experiment1 = Experiment.new(:name => 'Zero-gravity')
|
54
|
+
experiment2 = Experiment.new(:name => 'Physics 101')
|
55
|
+
experiment3 = Experiment.new(:name => 'Cell growth')
|
56
|
+
expect {
|
57
|
+
shuttle.experiments << experiment1
|
58
|
+
shuttle.save!
|
59
|
+
}.to change(Experiment, :count).by(1)
|
60
|
+
expect {
|
61
|
+
shuttle.experiments = [ experiment1, experiment2 ]
|
62
|
+
shuttle.save!
|
63
|
+
}.to change(Experiment, :count).by(1)
|
64
|
+
shuttle.experiment_ids.sort.should eq [ experiment1.id, experiment2.id ]
|
65
|
+
experiment3.save!
|
66
|
+
shuttle.experiment_ids = [ experiment1.id, experiment3.id ]
|
67
|
+
shuttle.experiment_ids.sort.should eq [ experiment1.id, experiment3.id ]
|
68
|
+
Experiment.last.space_ships.first.specialize.id.should eq shuttle.id
|
69
|
+
end
|
70
|
+
|
71
|
+
it "can use has_one associations defined in ascendant classes" do
|
72
|
+
# create dummy space ships to make sure the shuttle we'll cereate has a different database id than
|
73
|
+
# its associated captain
|
74
|
+
(1..2).map { SpaceShip.create }
|
75
|
+
shuttle = SpaceShuttle.create(:name => 'Discovery', :reliability => 100)
|
76
|
+
shuttle.id.should_not eq shuttle.convert_to(:space_ship).id
|
77
|
+
# test has_one functionality
|
78
|
+
captain = Captain.new(:name => 'Armstrong')
|
79
|
+
expect {
|
80
|
+
shuttle.captain = captain
|
81
|
+
shuttle.save!
|
82
|
+
}.to change(Captain, :count).by(1)
|
83
|
+
shuttle.reload
|
84
|
+
shuttle.captain.id.should eq captain.id
|
85
|
+
shuttle.captain.destroy
|
86
|
+
expect {
|
87
|
+
shuttle.create_captain(:name => 'Glenn')
|
88
|
+
}.to change(Captain, :count).by(1)
|
89
|
+
shuttle.captain.space_ship_id.should eq shuttle.convert_to(:space_ship).id
|
90
|
+
expect {
|
91
|
+
cap = shuttle.build_captain(:name => 'Aldrinn')
|
92
|
+
cap.save!
|
93
|
+
}.to change(Captain, :count).by(1)
|
94
|
+
shuttle.captain.space_ship_id.should eq shuttle.convert_to(:space_ship).id
|
95
|
+
end
|
96
|
+
|
97
|
+
it "can use has_and_belongs_to_many associations defined in ascendant classes" do
|
98
|
+
# create dummy space ships to make sure the shuttle we'll cereate has a different database id than
|
99
|
+
# its associated spaceship
|
100
|
+
(1..2).map { SpaceShip.create }
|
101
|
+
shuttle = SpaceShuttle.create(:name => 'Discovery', :reliability => 100)
|
102
|
+
shuttle.id.should_not eq shuttle.convert_to(:space_ship).id
|
103
|
+
# test has_and_belongs_to_many functionality
|
104
|
+
astronaut1 = Astronaut.new(:name => 'Armstrong')
|
105
|
+
astronaut2 = Astronaut.new(:name => 'Glenn')
|
106
|
+
astronaut3 = Astronaut.new(:name => 'Gagarin')
|
107
|
+
expect {
|
108
|
+
shuttle.astronauts << astronaut1
|
109
|
+
shuttle.save!
|
110
|
+
}.to change(Astronaut, :count).by(1)
|
111
|
+
shuttle.astronauts.first.name.should eq astronaut1.name
|
112
|
+
expect {
|
113
|
+
shuttle.astronauts = [ astronaut1, astronaut2 ]
|
114
|
+
shuttle.save!
|
115
|
+
}.to change(Astronaut, :count).by(1)
|
116
|
+
shuttle.astronaut_ids.sort.should eq [ astronaut1.id, astronaut2.id ]
|
117
|
+
astronaut3.save!
|
118
|
+
shuttle.astronaut_ids = [ astronaut1.id, astronaut3.id ]
|
119
|
+
shuttle.astronaut_ids.sort.should eq [ astronaut1.id, astronaut3.id ]
|
120
|
+
end
|
121
|
+
|
22
122
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbview_cti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.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: 2013-
|
12
|
+
date: 2013-10-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -69,6 +69,7 @@ extra_rdoc_files: []
|
|
69
69
|
files:
|
70
70
|
- .gitignore
|
71
71
|
- .travis.yml
|
72
|
+
- CHANGELOG.md
|
72
73
|
- Gemfile
|
73
74
|
- MIT-LICENSE
|
74
75
|
- README.md
|
@@ -99,7 +100,12 @@ files:
|
|
99
100
|
- spec/dummy-rails-3/app/helpers/application_helper.rb
|
100
101
|
- spec/dummy-rails-3/app/mailers/.gitkeep
|
101
102
|
- spec/dummy-rails-3/app/models/.gitkeep
|
103
|
+
- spec/dummy-rails-3/app/models/astronaut.rb
|
104
|
+
- spec/dummy-rails-3/app/models/captain.rb
|
102
105
|
- spec/dummy-rails-3/app/models/car.rb
|
106
|
+
- spec/dummy-rails-3/app/models/experiment.rb
|
107
|
+
- spec/dummy-rails-3/app/models/experiment_space_ship_performance.rb
|
108
|
+
- spec/dummy-rails-3/app/models/launch.rb
|
103
109
|
- spec/dummy-rails-3/app/models/motor_cycle.rb
|
104
110
|
- spec/dummy-rails-3/app/models/motor_vehicle.rb
|
105
111
|
- spec/dummy-rails-3/app/models/rocket_engine.rb
|
@@ -132,6 +138,13 @@ files:
|
|
132
138
|
- spec/dummy-rails-3/db/migrate/20130817014120_create_space_shuttles.rb
|
133
139
|
- spec/dummy-rails-3/db/migrate/20130817024220_create_rocket_engines.rb
|
134
140
|
- spec/dummy-rails-3/db/migrate/20130819040414_add_reliability_to_space_ships.rb
|
141
|
+
- spec/dummy-rails-3/db/migrate/20131021211442_create_launches.rb
|
142
|
+
- spec/dummy-rails-3/db/migrate/20131022010731_create_captains.rb
|
143
|
+
- spec/dummy-rails-3/db/migrate/20131022020536_create_astronauts.rb
|
144
|
+
- spec/dummy-rails-3/db/migrate/20131022020655_create_habtm_join_table.rb
|
145
|
+
- spec/dummy-rails-3/db/migrate/20131022030659_create_experiments.rb
|
146
|
+
- spec/dummy-rails-3/db/migrate/20131022030720_create_experiment_space_ship_performances.rb
|
147
|
+
- spec/dummy-rails-3/db/schema.rb
|
135
148
|
- spec/dummy-rails-3/lib/assets/.gitkeep
|
136
149
|
- spec/dummy-rails-3/log/.gitkeep
|
137
150
|
- spec/dummy-rails-3/public/404.html
|
@@ -170,6 +183,7 @@ files:
|
|
170
183
|
- spec/dummy-rails-4/config/initializers/wrap_parameters.rb
|
171
184
|
- spec/dummy-rails-4/config/locales/en.yml
|
172
185
|
- spec/dummy-rails-4/config/routes.rb
|
186
|
+
- spec/dummy-rails-4/db/schema.rb
|
173
187
|
- spec/dummy-rails-4/lib/assets/.keep
|
174
188
|
- spec/dummy-rails-4/log/.keep
|
175
189
|
- spec/dummy-rails-4/public/404.html
|
@@ -196,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
196
210
|
version: '0'
|
197
211
|
segments:
|
198
212
|
- 0
|
199
|
-
hash:
|
213
|
+
hash: -2732780512702174148
|
200
214
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
215
|
none: false
|
202
216
|
requirements:
|
@@ -205,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
219
|
version: '0'
|
206
220
|
segments:
|
207
221
|
- 0
|
208
|
-
hash:
|
222
|
+
hash: -2732780512702174148
|
209
223
|
requirements: []
|
210
224
|
rubyforge_project:
|
211
225
|
rubygems_version: 1.8.25
|