composite_primary_keys 11.2.0 → 11.3.1
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.
- checksums.yaml +4 -4
- data/History.rdoc +8 -0
- data/lib/composite_primary_keys.rb +1 -1
- data/lib/composite_primary_keys/base.rb +1 -1
- data/lib/composite_primary_keys/composite_arrays.rb +50 -7
- data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +1 -1
- data/lib/composite_primary_keys/persistence.rb +3 -2
- data/lib/composite_primary_keys/reflection.rb +15 -6
- data/lib/composite_primary_keys/relation/finder_methods.rb +5 -5
- data/lib/composite_primary_keys/version.rb +2 -2
- data/test/fixtures/cpk_with_default_value.rb +3 -0
- data/test/fixtures/cpk_with_default_values.yml +7 -0
- data/test/fixtures/db_definitions/mysql.sql +7 -1
- data/test/fixtures/db_definitions/oracle.drop.sql +3 -1
- data/test/fixtures/db_definitions/oracle.sql +8 -0
- data/test/fixtures/db_definitions/postgresql.sql +6 -0
- data/test/fixtures/db_definitions/sqlite.sql +6 -0
- data/test/fixtures/db_definitions/sqlserver.sql +8 -1
- data/test/test_composite_arrays.rb +14 -0
- data/test/test_create.rb +23 -1
- data/test/test_find.rb +8 -0
- data/test/test_ids.rb +3 -0
- metadata +7 -7
- data/test/db_test.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9568b1a0261ca52beff062804d3885a795fe4193c9289b140c49c3c36ea199fb
|
4
|
+
data.tar.gz: b458b36aa5e082fc060838953e56eaea26557c4a9570d161c03420ded1a8097e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70cbc4245e31da5701b16dfe7fa109cfe1f395311446537567804b4a378ea6cd2c33d771b00b72e6cd0833a6365b6adcba03a3df4e6564668d298d28f89abbad
|
7
|
+
data.tar.gz: 52df628c9b690b8855f8dbfb52394fca4f07d674aba598b00439cf036138ef73b7975f82c434c185b9c4d4ee4537f70070c27007c2bb5ff81422c513b1a5b96f
|
data/History.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 11.3.1 (2020-04-01)
|
2
|
+
* Fix overriding AbstractReflection for activerecord 5.2.4 (Sergey Semyonov)
|
3
|
+
* Fix handling CPK with fields containing comma (Sergey Semyonov)
|
4
|
+
* Fixed incorrect SQL condition for joining by CPK (Sergey Semyonov)
|
5
|
+
* Update travis.yml file (Sergey Semyonov)
|
6
|
+
* Add tests for composite keys with default values (Daniel Wiklund)
|
7
|
+
* Fix create record where one or more of the primary keys has a default value (Daniel Wiklund)
|
8
|
+
|
1
9
|
== 11.2.0 (2019-03-16)
|
2
10
|
* When creating new records, honor composite key autoincrementing fields if possible (Antti Pitkänen)
|
3
11
|
* Update Association#run to more closely match ActiveRecord (Fabian Mersch)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module CompositePrimaryKeys
|
2
2
|
ID_SEP = ','
|
3
3
|
ID_SET_SEP = ';'
|
4
|
+
ESCAPE_CHAR = '^'
|
4
5
|
|
5
6
|
module ArrayExtension
|
6
7
|
def to_composite_keys
|
@@ -8,12 +9,27 @@ module CompositePrimaryKeys
|
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
+
# Convert mixed representation of CPKs (by strings or arrays) to normalized
|
13
|
+
# representation (just by arrays).
|
14
|
+
#
|
15
|
+
# `ids` is Array that may contain:
|
16
|
+
# 1. A CPK represented by an array or a string.
|
17
|
+
# 2. An array of CPKs represented by arrays or strings.
|
18
|
+
#
|
19
|
+
# There is an issue. Let `ids` contain an array with several strings. We can't distinguish case 1
|
20
|
+
# from case 2 there in general. E.g. the item can be an array containing appropriate number of strings,
|
21
|
+
# and each string can contain appropriate number of commas. We consider case 2 to win there.
|
22
|
+
def self.normalize(ids, cpk_size)
|
12
23
|
ids.map do |id|
|
13
|
-
if id.
|
14
|
-
|
15
|
-
|
16
|
-
|
24
|
+
if Utils.cpk_as_array?(id, cpk_size) && id.any? { |item| !Utils.cpk_as_string?(item, cpk_size) }
|
25
|
+
# CPK as an array - case 1
|
26
|
+
id
|
27
|
+
elsif id.is_a?(Array)
|
28
|
+
# An array of CPKs - case 2
|
29
|
+
normalize(id, cpk_size)
|
30
|
+
elsif id.is_a?(String)
|
31
|
+
# CPK as a string - case 1
|
32
|
+
CompositeKeys.parse(id)
|
17
33
|
else
|
18
34
|
id
|
19
35
|
end
|
@@ -27,7 +43,7 @@ module CompositePrimaryKeys
|
|
27
43
|
when Array
|
28
44
|
value.to_composite_keys
|
29
45
|
when String
|
30
|
-
|
46
|
+
value.split(ID_SEP).map { |key| Utils.unescape_string_key(key) }.to_composite_keys
|
31
47
|
else
|
32
48
|
raise(ArgumentError, "Unsupported type: #{value}")
|
33
49
|
end
|
@@ -43,9 +59,36 @@ module CompositePrimaryKeys
|
|
43
59
|
|
44
60
|
def to_s
|
45
61
|
# Doing this makes it easier to parse Base#[](attr_name)
|
46
|
-
join(ID_SEP)
|
62
|
+
map { |key| Utils.escape_string_key(key.to_s) }.join(ID_SEP)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
module Utils
|
67
|
+
class << self
|
68
|
+
def escape_string_key(key)
|
69
|
+
key.gsub(Regexp.union(ESCAPE_CHAR, ID_SEP)) do |unsafe|
|
70
|
+
"#{ESCAPE_CHAR}#{unsafe.ord.to_s(16).upcase}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def unescape_string_key(key)
|
75
|
+
key.gsub(/#{Regexp.escape(ESCAPE_CHAR)}[0-9a-fA-F]{2}/) do |escaped|
|
76
|
+
char = escaped.slice(1, 2).hex.chr
|
77
|
+
(char == ESCAPE_CHAR || char == ID_SEP) ? char : escaped
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def cpk_as_array?(value, pk_size)
|
82
|
+
# We don't permit Array to be an element of CPK.
|
83
|
+
value.is_a?(Array) && value.size == pk_size && value.none? { |item| item.is_a?(Array) }
|
84
|
+
end
|
85
|
+
|
86
|
+
def cpk_as_string?(value, pk_size)
|
87
|
+
value.is_a?(String) && value.count(ID_SEP) == pk_size - 1
|
88
|
+
end
|
47
89
|
end
|
48
90
|
end
|
91
|
+
private_constant :Utils
|
49
92
|
end
|
50
93
|
|
51
94
|
Array.send(:include, CompositePrimaryKeys::ArrayExtension)
|
@@ -64,8 +64,9 @@ module ActiveRecord
|
|
64
64
|
new_id = self.class._insert_record(attributes_values)
|
65
65
|
|
66
66
|
# CPK
|
67
|
-
if self.composite?
|
68
|
-
|
67
|
+
if self.composite?
|
68
|
+
# Merge together the specified id with the new id (specified id gets precedence)
|
69
|
+
self.id = self.id.zip(Array(new_id)).map {|id1, id2| (id1 || id2)}
|
69
70
|
else
|
70
71
|
self.id ||= new_id if self.class.primary_key
|
71
72
|
end
|
@@ -1,19 +1,28 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Reflection
|
3
3
|
class AbstractReflection
|
4
|
-
|
4
|
+
# Overriding for activerecord v5.2.4
|
5
|
+
def join_scope(table, foreign_table, foreign_klass)
|
6
|
+
predicate_builder = predicate_builder(table)
|
7
|
+
scope_chain_items = join_scopes(table, predicate_builder)
|
8
|
+
klass_scope = klass_join_scope(table, predicate_builder)
|
9
|
+
|
5
10
|
key = join_keys.key
|
6
11
|
foreign_key = join_keys.foreign_key
|
7
12
|
|
8
13
|
# CPK
|
9
|
-
#
|
10
|
-
|
14
|
+
# klass_scope.where!(table[key].eq(foreign_table[foreign_key]))
|
15
|
+
klass_scope.where!(cpk_join_predicate(table, key, foreign_table, foreign_key))
|
16
|
+
|
17
|
+
if type
|
18
|
+
klass_scope.where!(type => foreign_klass.polymorphic_name)
|
19
|
+
end
|
11
20
|
|
12
21
|
if klass.finder_needs_type_condition?
|
13
|
-
|
14
|
-
else
|
15
|
-
constraint
|
22
|
+
klass_scope.where!(klass.send(:type_condition, table))
|
16
23
|
end
|
24
|
+
|
25
|
+
scope_chain_items.inject(klass_scope, &:merge!)
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
@@ -79,7 +79,7 @@ module CompositePrimaryKeys
|
|
79
79
|
|
80
80
|
# CPK
|
81
81
|
# expects_array = ids.first.kind_of?(Array)
|
82
|
-
ids = CompositePrimaryKeys.normalize(ids)
|
82
|
+
ids = CompositePrimaryKeys.normalize(ids, @klass.primary_keys.length)
|
83
83
|
expects_array = ids.flatten != ids.flatten(1)
|
84
84
|
return ids.first if expects_array && ids.first.empty?
|
85
85
|
|
@@ -156,10 +156,10 @@ module CompositePrimaryKeys
|
|
156
156
|
# CPK
|
157
157
|
if composite?
|
158
158
|
ids = if ids.length == 1
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
159
|
+
CompositePrimaryKeys::CompositeKeys.parse(ids.first)
|
160
|
+
else
|
161
|
+
ids.to_composite_keys
|
162
|
+
end
|
163
163
|
end
|
164
164
|
|
165
165
|
return find_some_ordered(ids) unless order_values.present?
|
@@ -215,4 +215,10 @@ create table pk_called_ids (
|
|
215
215
|
abbreviation varchar(50) default null,
|
216
216
|
description varchar(50) default null,
|
217
217
|
primary key (id, reference_code)
|
218
|
-
);
|
218
|
+
);
|
219
|
+
|
220
|
+
create table cpk_with_default_values (
|
221
|
+
record_id integer not null,
|
222
|
+
record_version varchar(50) default '' not null,
|
223
|
+
primary key (record_id, record_version)
|
224
|
+
);
|
@@ -45,4 +45,6 @@ drop table capitols;
|
|
45
45
|
drop table products_restaurants;
|
46
46
|
drop table employees_groups;
|
47
47
|
drop table pk_called_ids;
|
48
|
-
drop sequence pk_called_ids_seq;
|
48
|
+
drop sequence pk_called_ids_seq;
|
49
|
+
drop table cpk_with_default_values;
|
50
|
+
drop sequence cpk_with_default_values_seq;
|
@@ -234,3 +234,11 @@ create table pk_called_ids (
|
|
234
234
|
description varchar(50) default null,
|
235
235
|
constraint pk_called_ids_pk primary key (id, reference_code)
|
236
236
|
);
|
237
|
+
|
238
|
+
create sequence cpk_with_default_values_seq start with 1000;
|
239
|
+
|
240
|
+
create table cpk_with_default_values (
|
241
|
+
record_id int not null,
|
242
|
+
record_version varchar(50) default '' not null,
|
243
|
+
constraint cpk_with_default_values_pk primary key (record_id, record_version)
|
244
|
+
);
|
@@ -218,3 +218,9 @@ create table pk_called_ids (
|
|
218
218
|
description varchar(50) default null,
|
219
219
|
primary key (id, reference_code)
|
220
220
|
);
|
221
|
+
|
222
|
+
create table cpk_with_default_values (
|
223
|
+
record_id serial not null,
|
224
|
+
record_version varchar(50) default '' not null,
|
225
|
+
primary key (record_id, record_version)
|
226
|
+
);
|
@@ -204,3 +204,9 @@ create table pk_called_ids (
|
|
204
204
|
description varchar(50) default null,
|
205
205
|
primary key (id, reference_code)
|
206
206
|
);
|
207
|
+
|
208
|
+
create table cpk_with_default_values (
|
209
|
+
record_id integer not null,
|
210
|
+
record_version varchar(50) default '' not null,
|
211
|
+
primary key (record_id, record_version)
|
212
|
+
);
|
@@ -210,4 +210,11 @@ CREATE TABLE pk_called_ids (
|
|
210
210
|
description [varchar](50) default null
|
211
211
|
CONSTRAINT [pk_called_ids_pk] PRIMARY KEY
|
212
212
|
( [id], [reference_code] )
|
213
|
-
);
|
213
|
+
);
|
214
|
+
|
215
|
+
CREATE TABLE cpk_with_default_values (
|
216
|
+
record_id [int] IDENTITY(1000,1) NOT NULL,
|
217
|
+
record_version [varchar](50) default '' NOT NULL
|
218
|
+
CONSTRAINT [cpk_with_default_values_pk] PRIMARY KEY
|
219
|
+
( [record_id], [record_version] )
|
220
|
+
);
|
@@ -21,4 +21,18 @@ class CompositeArraysTest < ActiveSupport::TestCase
|
|
21
21
|
assert_equal CompositePrimaryKeys::CompositeKeys, keys.class
|
22
22
|
assert_equal '1,2,3', keys.to_s
|
23
23
|
end
|
24
|
+
|
25
|
+
def test_parse
|
26
|
+
assert_equal ['1', '2'], CompositePrimaryKeys::CompositeKeys.parse('1,2')
|
27
|
+
assert_equal ['The USA', '^Washington, D.C.'],
|
28
|
+
CompositePrimaryKeys::CompositeKeys.parse('The USA,^5EWashington^2C D.C.')
|
29
|
+
assert_equal ['The USA', '^Washington, D.C.'],
|
30
|
+
CompositePrimaryKeys::CompositeKeys.parse(['The USA', '^Washington, D.C.'])
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_to_s
|
34
|
+
assert_equal '1,2', CompositePrimaryKeys::CompositeKeys.new([1, 2]).to_s
|
35
|
+
assert_equal 'The USA,^5EWashington^2C D.C.',
|
36
|
+
CompositePrimaryKeys::CompositeKeys.new(['The USA', '^Washington, D.C.']).to_s
|
37
|
+
end
|
24
38
|
end
|
data/test/test_create.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path('../abstract_unit', __FILE__)
|
2
2
|
|
3
3
|
class TestCreate < ActiveSupport::TestCase
|
4
|
-
fixtures :articles, :students, :dorms, :rooms, :room_assignments, :reference_types, :reference_codes, :streets, :suburbs
|
4
|
+
fixtures :articles, :students, :dorms, :rooms, :room_assignments, :reference_types, :reference_codes, :streets, :suburbs, :cpk_with_default_values
|
5
5
|
|
6
6
|
CLASSES = {
|
7
7
|
:single => {
|
@@ -172,4 +172,26 @@ class TestCreate < ActiveSupport::TestCase
|
|
172
172
|
|
173
173
|
assert_equal('Validation failed: Id has already been taken', error.to_s)
|
174
174
|
end
|
175
|
+
|
176
|
+
def test_find_or_create_by
|
177
|
+
suburb = Suburb.find_by(:city_id => 3, :suburb_id => 1)
|
178
|
+
assert_nil(suburb)
|
179
|
+
|
180
|
+
suburb = Suburb.find_or_create_by!(:name => 'New Suburb', :city_id => 3, :suburb_id => 1)
|
181
|
+
refute_nil(suburb)
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_create_when_pk_has_default_value
|
185
|
+
first = CpkWithDefaultValue.create!
|
186
|
+
refute_nil(first.record_id)
|
187
|
+
assert_equal('', first.record_version)
|
188
|
+
|
189
|
+
second = CpkWithDefaultValue.create!(record_id: first.record_id, record_version: 'Same id, different version')
|
190
|
+
assert_equal(first.record_id, second.record_id)
|
191
|
+
assert_equal('Same id, different version', second.record_version)
|
192
|
+
|
193
|
+
third = CpkWithDefaultValue.create!(record_version: 'Created by version only')
|
194
|
+
refute_nil(third.record_id)
|
195
|
+
assert_equal('Created by version only', third.record_version)
|
196
|
+
end
|
175
197
|
end
|
data/test/test_find.rb
CHANGED
@@ -41,6 +41,14 @@ class TestFind < ActiveSupport::TestCase
|
|
41
41
|
assert_equal(['The Netherlands', 'Amsterdam'], capitol.id)
|
42
42
|
end
|
43
43
|
|
44
|
+
def test_find_with_strings_with_comma_as_composite_keys
|
45
|
+
capitol = Capitol.create!(country: 'The USA', city: 'Washington, D.C.')
|
46
|
+
assert_equal ['The USA', 'Washington, D.C.'], capitol.id
|
47
|
+
|
48
|
+
assert_equal capitol, Capitol.find(['The USA', 'Washington, D.C.'])
|
49
|
+
assert_equal capitol, Capitol.find(capitol.to_param)
|
50
|
+
end
|
51
|
+
|
44
52
|
def test_find_each
|
45
53
|
room_assignments = []
|
46
54
|
RoomAssignment.find_each(:batch_size => 2) do |assignment|
|
data/test/test_ids.rb
CHANGED
@@ -40,6 +40,9 @@ class TestIds < ActiveSupport::TestCase
|
|
40
40
|
testing_with do
|
41
41
|
assert_equal '1,1', @first.to_param if composite?
|
42
42
|
end
|
43
|
+
|
44
|
+
capitol = Capitol.create!(country: 'The USA', city: 'Washington, D.C.')
|
45
|
+
assert_equal 'The USA,Washington^2C D.C.', capitol.to_param
|
43
46
|
end
|
44
47
|
|
45
48
|
def test_ids_to_s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composite_primary_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 11.
|
4
|
+
version: 11.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Savage
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.2.
|
19
|
+
version: 5.2.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.2.
|
26
|
+
version: 5.2.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,13 +147,14 @@ files:
|
|
147
147
|
- test/connections/databases.ci.yml
|
148
148
|
- test/connections/databases.example.yml
|
149
149
|
- test/connections/databases.yml
|
150
|
-
- test/db_test.rb
|
151
150
|
- test/fixtures/article.rb
|
152
151
|
- test/fixtures/articles.yml
|
153
152
|
- test/fixtures/capitol.rb
|
154
153
|
- test/fixtures/capitols.yml
|
155
154
|
- test/fixtures/comment.rb
|
156
155
|
- test/fixtures/comments.yml
|
156
|
+
- test/fixtures/cpk_with_default_value.rb
|
157
|
+
- test/fixtures/cpk_with_default_values.yml
|
157
158
|
- test/fixtures/db_definitions/db2-create-tables.sql
|
158
159
|
- test/fixtures/db_definitions/db2-drop-tables.sql
|
159
160
|
- test/fixtures/db_definitions/mysql.sql
|
@@ -272,13 +273,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
273
|
- !ruby/object:Gem::Version
|
273
274
|
version: '0'
|
274
275
|
requirements: []
|
275
|
-
rubygems_version: 3.
|
276
|
+
rubygems_version: 3.1.2
|
276
277
|
signing_key:
|
277
278
|
specification_version: 4
|
278
279
|
summary: Composite key support for ActiveRecord
|
279
280
|
test_files:
|
280
281
|
- test/abstract_unit.rb
|
281
|
-
- test/db_test.rb
|
282
282
|
- test/README_tests.rdoc
|
283
283
|
- test/setup.rb
|
284
284
|
- test/test_aliases.rb
|
data/test/db_test.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# assoc_test.rb
|
2
|
-
|
3
|
-
path = File.expand_path(File.join(File.basename(__FILE__), "..", "lib", "composite_primary_keys"))
|
4
|
-
puts path
|
5
|
-
|
6
|
-
require File.join(path)
|
7
|
-
require 'active_record'
|
8
|
-
|
9
|
-
$configuration = {
|
10
|
-
:adapter => 'postgresql',
|
11
|
-
:database => 'cpk_test',
|
12
|
-
:username => 'postgres'
|
13
|
-
}
|
14
|
-
|
15
|
-
ActiveRecord::Base.establish_connection($configuration) unless ActiveRecord::Base.connected?
|
16
|
-
|
17
|
-
module GlobePG
|
18
|
-
class PGBase < ActiveRecord::Base
|
19
|
-
self.abstract_class = true
|
20
|
-
# establish_connection($configuration) unless connected?
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module GlobePG
|
25
|
-
class TeacherToSchool < PGBase
|
26
|
-
set_table_name 'teacher_to_school'
|
27
|
-
self.primary_keys = ['teacherid', 'schoolid']
|
28
|
-
|
29
|
-
belongs_to :globe_teacher, :foreign_key => 'teacherid'
|
30
|
-
belongs_to :globe_school, :foreign_key => 'schoolid'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
module GlobePG
|
35
|
-
class GlobeSchool < PGBase
|
36
|
-
set_table_name 'globe_school'
|
37
|
-
self.primary_key = 'schoolid'
|
38
|
-
has_many :teacher_to_schools, :foreign_key => :schoolid
|
39
|
-
has_many :globe_teachers, :through => :teacher_to_schools
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
module GlobePG
|
44
|
-
class GlobeTeacher < PGBase
|
45
|
-
set_table_name 'globe_teacher'
|
46
|
-
self.primary_key = 'teacherid'
|
47
|
-
has_many :teacher_to_schools, :foreign_key => :teacherid
|
48
|
-
has_many :globe_schools, :through => :teacher_to_schools
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
teacher = GlobePG::GlobeTeacher.find_by_teacherid('ZZGLOBEY')
|
53
|
-
p teacher.globe_schools
|