sportdb-models 1.19.0 → 2.0.3

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -20
  3. data/Manifest.txt +27 -38
  4. data/README.md +31 -31
  5. data/Rakefile +32 -32
  6. data/lib/sportdb/models.rb +212 -159
  7. data/lib/sportdb/{deleter.rb → models/deleter.rb} +3 -9
  8. data/lib/sportdb/models/formats.rb +23 -0
  9. data/lib/sportdb/models/models/assoc.rb +38 -0
  10. data/lib/sportdb/models/{badge.rb → models/badge.rb} +14 -14
  11. data/lib/sportdb/models/models/event.rb +55 -0
  12. data/lib/sportdb/models/{forward.rb → models/forward.rb} +55 -55
  13. data/lib/sportdb/models/{goal.rb → models/goal.rb} +15 -15
  14. data/lib/sportdb/models/models/ground.rb +16 -0
  15. data/lib/sportdb/models/{group.rb → models/group.rb} +10 -7
  16. data/lib/sportdb/models/models/league.rb +20 -0
  17. data/lib/sportdb/models/{roster.rb → models/lineup.rb} +17 -18
  18. data/lib/sportdb/models/{game.rb → models/match.rb} +18 -61
  19. data/lib/sportdb/models/{person.rb → models/person.rb} +21 -21
  20. data/lib/sportdb/models/{round.rb → models/round.rb} +1 -6
  21. data/lib/sportdb/models/{season.rb → models/season.rb} +15 -14
  22. data/lib/sportdb/models/{stage.rb → models/stage.rb} +9 -5
  23. data/lib/sportdb/models/{stats/alltime_standing_entry.rb → models/stats/alltime_standing.rb} +9 -1
  24. data/lib/sportdb/models/{stats/event_standing_entry.rb → models/stats/event_standing.rb} +31 -21
  25. data/lib/sportdb/models/{stats/group_standing_entry.rb → models/stats/group_standing.rb} +10 -1
  26. data/lib/sportdb/models/models/team.rb +56 -0
  27. data/lib/sportdb/models/{world → models/world}/city.rb +2 -2
  28. data/lib/sportdb/models/{world → models/world}/continent.rb +20 -20
  29. data/lib/sportdb/models/{world → models/world}/country.rb +0 -0
  30. data/lib/sportdb/models/{world → models/world}/state.rb +19 -19
  31. data/lib/sportdb/models/schema.rb +466 -0
  32. data/lib/sportdb/models/stats.rb +23 -0
  33. data/lib/sportdb/models/utils.rb +24 -24
  34. data/lib/sportdb/{version.rb → models/version.rb} +27 -22
  35. data/test/helper.rb +46 -42
  36. data/test/test_changes.rb +38 -38
  37. data/test/test_cursor.rb +15 -15
  38. data/test/test_winner.rb +75 -70
  39. metadata +39 -44
  40. data/lib/sportdb/calc.rb +0 -279
  41. data/lib/sportdb/models/assoc.rb +0 -106
  42. data/lib/sportdb/models/assoc_assoc.rb +0 -15
  43. data/lib/sportdb/models/event.rb +0 -66
  44. data/lib/sportdb/models/event_ground.rb +0 -15
  45. data/lib/sportdb/models/event_team.rb +0 -16
  46. data/lib/sportdb/models/ground.rb +0 -100
  47. data/lib/sportdb/models/group_team.rb +0 -14
  48. data/lib/sportdb/models/league.rb +0 -83
  49. data/lib/sportdb/models/stage_team.rb +0 -14
  50. data/lib/sportdb/models/stats/alltime_standing.rb +0 -44
  51. data/lib/sportdb/models/stats/event_standing.rb +0 -55
  52. data/lib/sportdb/models/stats/group_standing.rb +0 -50
  53. data/lib/sportdb/models/team.rb +0 -119
  54. data/lib/sportdb/models/team_compat.rb +0 -64
  55. data/lib/sportdb/patterns.rb +0 -37
  56. data/lib/sportdb/schema.rb +0 -397
  57. data/lib/sportdb/standings.rb +0 -178
  58. data/lib/sportdb/stats.rb +0 -27
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.0
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-11 00:00:00.000000000 Z
11
+ date: 2020-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: worlddb-models
@@ -42,30 +42,36 @@ dependencies:
42
42
  name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '4.0'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '7'
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
- - - "~>"
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
57
  version: '4.0'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '7'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: hoe
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '3.16'
67
+ version: '3.22'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: '3.16'
74
+ version: '3.22'
69
75
  description: sportdb-models - sport.db schema 'n' models for easy (re)use
70
76
  email: opensport@googlegroups.com
71
77
  executables: []
@@ -79,46 +85,35 @@ files:
79
85
  - Manifest.txt
80
86
  - README.md
81
87
  - Rakefile
82
- - lib/sportdb/calc.rb
83
- - lib/sportdb/deleter.rb
84
88
  - lib/sportdb/models.rb
85
- - lib/sportdb/models/assoc.rb
86
- - lib/sportdb/models/assoc_assoc.rb
87
- - lib/sportdb/models/badge.rb
88
- - lib/sportdb/models/event.rb
89
- - lib/sportdb/models/event_ground.rb
90
- - lib/sportdb/models/event_team.rb
91
- - lib/sportdb/models/forward.rb
92
- - lib/sportdb/models/game.rb
93
- - lib/sportdb/models/goal.rb
94
- - lib/sportdb/models/ground.rb
95
- - lib/sportdb/models/group.rb
96
- - lib/sportdb/models/group_team.rb
97
- - lib/sportdb/models/league.rb
98
- - lib/sportdb/models/person.rb
99
- - lib/sportdb/models/roster.rb
100
- - lib/sportdb/models/round.rb
101
- - lib/sportdb/models/season.rb
102
- - lib/sportdb/models/stage.rb
103
- - lib/sportdb/models/stage_team.rb
104
- - lib/sportdb/models/stats/alltime_standing.rb
105
- - lib/sportdb/models/stats/alltime_standing_entry.rb
106
- - lib/sportdb/models/stats/event_standing.rb
107
- - lib/sportdb/models/stats/event_standing_entry.rb
108
- - lib/sportdb/models/stats/group_standing.rb
109
- - lib/sportdb/models/stats/group_standing_entry.rb
110
- - lib/sportdb/models/team.rb
111
- - lib/sportdb/models/team_compat.rb
89
+ - lib/sportdb/models/deleter.rb
90
+ - lib/sportdb/models/formats.rb
91
+ - lib/sportdb/models/models/assoc.rb
92
+ - lib/sportdb/models/models/badge.rb
93
+ - lib/sportdb/models/models/event.rb
94
+ - lib/sportdb/models/models/forward.rb
95
+ - lib/sportdb/models/models/goal.rb
96
+ - lib/sportdb/models/models/ground.rb
97
+ - lib/sportdb/models/models/group.rb
98
+ - lib/sportdb/models/models/league.rb
99
+ - lib/sportdb/models/models/lineup.rb
100
+ - lib/sportdb/models/models/match.rb
101
+ - lib/sportdb/models/models/person.rb
102
+ - lib/sportdb/models/models/round.rb
103
+ - lib/sportdb/models/models/season.rb
104
+ - lib/sportdb/models/models/stage.rb
105
+ - lib/sportdb/models/models/stats/alltime_standing.rb
106
+ - lib/sportdb/models/models/stats/event_standing.rb
107
+ - lib/sportdb/models/models/stats/group_standing.rb
108
+ - lib/sportdb/models/models/team.rb
109
+ - lib/sportdb/models/models/world/city.rb
110
+ - lib/sportdb/models/models/world/continent.rb
111
+ - lib/sportdb/models/models/world/country.rb
112
+ - lib/sportdb/models/models/world/state.rb
113
+ - lib/sportdb/models/schema.rb
114
+ - lib/sportdb/models/stats.rb
112
115
  - lib/sportdb/models/utils.rb
113
- - lib/sportdb/models/world/city.rb
114
- - lib/sportdb/models/world/continent.rb
115
- - lib/sportdb/models/world/country.rb
116
- - lib/sportdb/models/world/state.rb
117
- - lib/sportdb/patterns.rb
118
- - lib/sportdb/schema.rb
119
- - lib/sportdb/standings.rb
120
- - lib/sportdb/stats.rb
121
- - lib/sportdb/version.rb
116
+ - lib/sportdb/models/version.rb
122
117
  - test/helper.rb
123
118
  - test/test_changes.rb
124
119
  - test/test_cursor.rb
@@ -1,279 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
-
5
- ############
6
- ##
7
- ## fix/todo: obsolete
8
- ## - use new Standings class
9
-
10
-
11
- ##############################################
12
- # helper/ builds standings table in memory
13
- # - find a better module name for StandingsHelper ?? why? why not?
14
-
15
-
16
- module StandingsHelper
17
-
18
- ## todo:
19
- ## add team_id to struct - why? why not? - saves a db lookup?
20
- class Stats
21
- ### fix/todo: change/rename :pos to :rank
22
- attr_accessor :pos, :played, :won, :lost, :drawn,
23
- :goals_for, :goals_against, :pts,
24
- :recs
25
-
26
- def initialize
27
- @pos = nil # use 0? why? why not?
28
- @played = 0
29
- @won = 0
30
- @lost = 0
31
- @drawn = 0
32
- @goals_for = 0
33
- @goals_against = 0
34
- @pts = 0
35
- @recs = 0
36
- # note: appearances (event) count or similar
37
- # is recs counter (number of (stats) records)
38
- end
39
-
40
- def add( rec )
41
- ### fix: add plus + operator too!
42
-
43
- # note: will NOT update/add pos (ranking)
44
- self.played += rec.played
45
- self.won += rec.won
46
- self.lost += rec.lost
47
- self.drawn += rec.drawn
48
- self.goals_for += rec.goals_for
49
- self.goals_against += rec.goals_against
50
- self.pts += rec.pts
51
- self.recs += rec.recs
52
-
53
- self # return self stats rec
54
- end # method add
55
- end # class Stats
56
-
57
-
58
- def self.calc( games, opts={} )
59
-
60
- ##
61
- # possible opts include:
62
- # pts_won: 3 or 2 or n (default 3)
63
- # pts_exclude_scorep false or true (default false) -- exclude penalty shotout scores (e.g. count a draw/tie - no winner)
64
- #
65
- recs = calc_stats( games, opts )
66
-
67
- ## update pos (that is, ranking e.g. 1.,2., 3. etc.)
68
- recs= update_ranking( recs )
69
-
70
- pp recs
71
- recs
72
- end
73
-
74
-
75
-
76
- def self.calc_for_events( events, opts={} )
77
-
78
- ## todo:
79
- ## - add tracker for appeareances (stats records counter)
80
-
81
- alltime_recs = {} # stats recs indexed by team_key
82
-
83
- events.each do |event|
84
- puts " update standings for #{event.title}"
85
- recs = calc_stats( event.games, opts )
86
-
87
- recs.each do |team_key, rec|
88
- alltime_rec = alltime_recs[ team_key ] || Stats.new
89
-
90
- ## add stats values
91
- alltime_rec.add( rec )
92
-
93
- alltime_recs[ team_key ] = alltime_rec
94
- end
95
- end
96
-
97
-
98
- ### fix:
99
- # - make merge team into a helper method (for reuse)
100
-
101
- ## check for merging teams
102
- # e.g. all time world cup
103
- # Germany incl. West Germany
104
- # Russia incl. Soviet Union etc.
105
-
106
- # todo: change opts para to :includes instead of :merge ? why? why not??
107
-
108
- merge = opts[:merge]
109
- if merge
110
- puts " merging teams (stats records):"
111
- pp merge
112
-
113
- merge.each do |k,v|
114
- # note: assume key is destition team key and
115
- # value is source team key e.g. 'GER' => 'FRG'
116
- # or array (for mulitple teamss e.g. 'GER' => ['FRG','GDR']
117
- team_key_dest = k.to_s
118
-
119
- if v.kind_of? Array
120
- team_keys_src = v
121
- else
122
- team_keys_src = [v] # turn single value arg into array w/ single item
123
- end
124
- team_keys_src = team_keys_src.map { |src| src.to_s } # turn all to string (might be symbol)
125
-
126
- alltime_rec_dest = alltime_recs[ team_key_dest ] || Stats.new
127
-
128
- team_keys_src.each do |team_key_src|
129
- alltime_rec_src = alltime_recs[ team_key_src]
130
-
131
- if alltime_rec_src # stats record found?
132
- alltime_rec_dest.add( alltime_rec_src ) # add stats values
133
- alltime_recs.delete( team_key_src ) # remove old src entry
134
- end
135
- end
136
-
137
- alltime_recs[ team_key_dest ] = alltime_rec_dest
138
- end
139
- end
140
-
141
- ## update pos (that is, ranking e.g. 1.,2., 3. etc.)
142
- alltime_recs= update_ranking( alltime_recs )
143
-
144
- ## pp alltime_recs
145
- alltime_recs
146
- end
147
-
148
-
149
-
150
- def self.calc_stats( games, opts={} )
151
-
152
- ## fix:
153
- # passing in e.g. pts for win (3? 2? etc.)
154
- # default to 3 for now
155
-
156
- # note:
157
- # returns stats records w/ stats records counter always set to one (recs==1)
158
-
159
- ## todo/fix: find a better way to include logger (do NOT hardcode usage of root logger)!!!
160
- logger = LogUtils::Logger.root
161
-
162
-
163
- ## lets you pass in 2 as an alterantive, for example
164
- pts_won = opts[:pts_won] || 3
165
-
166
- ## lets you exclude penalty shootout (e.g. match gets scored as draw/tie 1 pt each)
167
- # e.g. why? used for alltime standings formula in world cup, for example
168
- # todo: check other standings - exclude penalty shootout too - e.g. championsleague ?? if yes - make it true as default??
169
- pts_exclude_scorep = opts[:pts_exclude_scorep].present? ? opts[:pts_exclude_scorep] : false
170
-
171
-
172
- recs = {}
173
-
174
- games.each_with_index do |g,i| # note: index(i) starts w/ zero (0)
175
- puts " [#{i+1}] #{g.team1.title} - #{g.team2.title} #{g.score_str}"
176
- unless g.over?
177
- puts " !!!! skipping match - not yet over (play_at date in the future)"
178
- next
179
- end
180
- unless g.complete?
181
- logger.error "[StandingsHelper.calc_stats] skipping match #{g.team1.title} - #{g.team2.title} - scores incomplete #{g.score_str}"
182
- next
183
- end
184
-
185
- rec1 = recs[ g.team1.key ] || Stats.new
186
- rec2 = recs[ g.team2.key ] || Stats.new
187
-
188
- ## set stats records counter to one if new (first) record update
189
- rec1.recs = 1 if rec1.recs == 0
190
- rec2.recs = 1 if rec2.recs == 0
191
-
192
- rec1.played += 1
193
- rec2.played += 1
194
-
195
- ## check - if winner (excludes penalty shootout scores in calc? start w/ extra time e.g winneret)
196
- if pts_exclude_scorep
197
- winner = g.winneret || g.winner90 ## if no extra time (et) score; try 90min (regular time score)
198
- else
199
- winner = g.winner ## note: might include penalty shoot scores
200
- end
201
-
202
- if winner == 1
203
- rec1.won += 1
204
- rec2.lost += 1
205
- rec1.pts += pts_won
206
- elsif winner == 2
207
- rec1.lost += 1
208
- rec2.won += 1
209
- rec2.pts += pts_won
210
- else ## assume drawn/tie (that is, 0)
211
- rec1.drawn += 1
212
- rec2.drawn += 1
213
- rec1.pts += 1
214
- rec2.pts += 1
215
- end
216
-
217
- rec1.goals_for += g.score1
218
- rec1.goals_against += g.score2
219
-
220
- rec2.goals_for += g.score2
221
- rec2.goals_against += g.score1
222
-
223
- ## add overtime and penalty??
224
- ## - for now add only overtime if present
225
-
226
- rec1.goals_for += (g.score1et-g.score1) if g.score1et.present?
227
- rec1.goals_against += (g.score2et-g.score2) if g.score2et.present?
228
-
229
- rec2.goals_for += (g.score2et-g.score2) if g.score2et.present?
230
- rec2.goals_against += (g.score1et-g.score1) if g.score1et.present?
231
-
232
- recs[ g.team1.key ] = rec1
233
- recs[ g.team2.key ] = rec2
234
- end # each game
235
-
236
- recs # return records; hash indexed by team key
237
- end # method calc
238
-
239
-
240
- def self.update_ranking( recs )
241
- #############################
242
- ### calc ranking / pos
243
- ##
244
- ## fix/allow sampe pos e.g. all 1 or more than one team 3rd etc.
245
- ## see sportbook for an example
246
-
247
- # build array from hash
248
- ary = []
249
- recs.each do |k,v|
250
- ary << [k,v]
251
- end
252
-
253
- ary.sort! do |l,r|
254
- ## note: reverse order (thus, change l,r to r,l)
255
- value = r[1].pts <=> l[1].pts
256
- if value == 0 # same pts try goal diff
257
- value = (r[1].goals_for-r[1].goals_against) <=> (l[1].goals_for-l[1].goals_against)
258
- if value == 0 # same goal diff too; try assume more goals better for now
259
- value = r[1].goals_for <=> l[1].goals_for
260
- end
261
- end
262
- value
263
- end
264
-
265
- ## update pos using ordered array
266
- ary.each_with_index do |rec,i|
267
- k = rec[0]
268
- v = rec[1]
269
- v.pos = i+1 ## add ranking (e.g. 1,2,3 etc.) - note: i starts w/ zero (0)
270
- recs[ k ] = v ## update recs
271
- end
272
-
273
- recs
274
- end # method update_ranking
275
-
276
-
277
- end # module StandingsHelper
278
-
279
- end # module SportDb
@@ -1,106 +0,0 @@
1
- module SportDb
2
- module Model
3
-
4
- class Assoc < ActiveRecord::Base
5
-
6
- has_many :parent_assoc_assocs, class_name: 'AssocAssoc', foreign_key: 'assoc2_id'
7
- ## child_assocs - use child_assocs? - (direct) member/child assocs instead of member?
8
- has_many :member_assoc_assocs, class_name: 'AssocAssoc', foreign_key: 'assoc1_id'
9
-
10
-
11
- ## note: split member_assocs into two sets (into national=true and national=false)
12
- # e.g. fifa has six member confederations (non-national) and 216 national assocs
13
- if ActiveRecord::VERSION::MAJOR == 3
14
- has_many :all_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
15
- has_many :sub_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs, conditions: { national: false }
16
- has_many :national_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs, conditions: { national: true }
17
- else
18
- ## note: includes all member (sub assocs + national assocs) - rename to member_assocs?
19
- has_many :all_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
20
- ## use zone/region as name instead of sub ( for confederatons,zones,etc.)
21
- has_many :sub_assocs, -> { where( national: false ) }, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
22
- has_many :national_assocs, -> { where( national: true ) }, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
23
- end
24
-
25
- ## for now can have more than one (direct) parent assoc
26
- ## e.g. Africa Fed and Arab League Fed
27
- has_many :parent_assocs, class_name: 'Assoc', :source => :assoc1, :through => :parent_assoc_assocs
28
-
29
- # assoc only can have one direct team for now (uses belongs_to on other side)
30
- # has_one :team
31
-
32
-
33
- def self.create_or_update_from_values( new_attributes, values )
34
-
35
- ## fix: add/configure logger for ActiveRecord!!!
36
- logger = LogUtils::Logger.root
37
-
38
- assoc_keys = [] # by default no association (e.g. fifa,uefa,etc.)
39
-
40
- ## check optional values
41
- values.each_with_index do |value, index|
42
- if value =~ /^(18|19|20)[0-9]{2}$/ ## assume founding year -- allow 18|19|20
43
- ## logger.info " founding/opening year #{value}"
44
- new_attributes[ :since ] = value.to_i
45
- elsif value =~ /\/{2}/ # assume it's an address line e.g. xx // xx
46
- logger.info " found address line #{value}"
47
- ## new_attributes[ :address ] = value
48
- elsif value =~ /^(?:[a-z]{2}\.)?wikipedia:/ # assume it's wikipedia e.g. [es.]wikipedia:
49
- logger.info " found wikipedia line #{value}; skipping for now"
50
- elsif value =~ /(^www\.)|(\.com$)/ # FIX: !!!! use a better matcher not just www. and .com
51
- new_attributes[ :web ] = value
52
- ## elsif value =~ /^[a-z]{2}$/ ## assume two-letter country key e.g. at,de,mx,etc.
53
- ## ## fix: allow country letter with three e.g. eng,sco,wal,nir, etc. !!!
54
- ## value_country = Country.find_by_key!( value )
55
- ## new_attributes[ :country_id ] = value_country.id
56
- elsif value =~ /^[a-z]{2}$/ ## assume two-letter country key e.g. at,de,mx,etc.
57
- ## fix: allow country letter with three e.g. eng,sco,wal,nir, etc. !!!
58
- ## fix: if country does NOT match / NOT found - just coninue w/ next match!!!!
59
- # - just issue an error/warn do NOT crash
60
- value_country = Country.find_by_key!( value )
61
- new_attributes[ :country_id ] = value_country.id
62
- ## note: if country present - assume it's a national assoc, thus, set flag to true
63
- new_attributes[ :national ] = true
64
- elsif value =~ /^[a-z|]+$/ ## looks like a tag list e.g. fifa|uefa or fifa|caf or ocf?
65
- logger.info " trying adding assocs using keys >#{value}<"
66
- assoc_keys = value.split('|')
67
- else
68
- ## todo: assume title2 ??
69
- # issue warning: unknown type for value
70
- logger.warn "unknown type for value >#{value}< - key #{new_attributes[:key]}"
71
- end
72
- end
73
-
74
- rec = Assoc.find_by_key( new_attributes[ :key ] )
75
- if rec.present?
76
- logger.debug "update Assoc #{rec.id}-#{rec.key}:"
77
- else
78
- logger.debug "create Assoc:"
79
- rec = Assoc.new
80
- end
81
-
82
- logger.debug new_attributes.to_json
83
-
84
- rec.update_attributes!( new_attributes )
85
-
86
- unless assoc_keys.empty?
87
- ## add team to assocs
88
- assoc_keys.each do |assoc_key|
89
- assoc = Assoc.find_by_key!( assoc_key )
90
- logger.debug " adding assoc to assoc >#{assoc.title}<"
91
-
92
- ### todo/fix: how can we delete assoc_assocs? for now only update n create
93
- assoc_assoc = AssocAssoc.where( assoc1_id: assoc.id, assoc2_id: rec.id ).first
94
- if assoc_assoc.nil? ## create if does NOT exist yet
95
- AssocAssoc.create!( assoc1_id: assoc.id, assoc2_id: rec.id )
96
- end
97
- end
98
- end
99
-
100
- end # create_or_update_from_values
101
-
102
- end # class Assoc
103
-
104
-
105
- end # module Model
106
- end # module SportDb