beerdb-models 0.10.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.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/HISTORY.md +3 -0
- data/Manifest.txt +25 -0
- data/README.md +97 -0
- data/Rakefile +31 -0
- data/lib/beerdb/deleter.rb +27 -0
- data/lib/beerdb/models.rb +103 -0
- data/lib/beerdb/models/beer.rb +201 -0
- data/lib/beerdb/models/brand.rb +62 -0
- data/lib/beerdb/models/brewery.rb +256 -0
- data/lib/beerdb/models/forward.rb +46 -0
- data/lib/beerdb/models/tag.rb +13 -0
- data/lib/beerdb/models/world/city.rb +14 -0
- data/lib/beerdb/models/world/country.rb +14 -0
- data/lib/beerdb/models/world/region.rb +14 -0
- data/lib/beerdb/reader.rb +219 -0
- data/lib/beerdb/reader_file.rb +62 -0
- data/lib/beerdb/reader_zip.rb +112 -0
- data/lib/beerdb/schema.rb +195 -0
- data/lib/beerdb/serializers/beer.rb +45 -0
- data/lib/beerdb/serializers/brewery.rb +46 -0
- data/lib/beerdb/stats.rb +27 -0
- data/lib/beerdb/version.rb +21 -0
- data/test/helper.rb +63 -0
- data/test/test_fixture_matchers.rb +85 -0
- data/test/test_values.rb +240 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 81cbea581c2fdb972632982aa387c16ad9c8120c
|
4
|
+
data.tar.gz: 8865a095da2b63a7e11447452226d29af752d8d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 541a57ed981411438c18a0e40f9d276c84e9922d3dbe084aec5c4b807ec425e72b502cd5d15598278200fd1e514b8d1574b08094a440a7dad67f69dbf3a650f1
|
7
|
+
data.tar.gz: e9cc5b27bb0e342ca75e70b052743b5fe23b9b5fff12c77081028476d59fd5d7433f25d6b07273375aae9dc414863ecaa5eebdefdce5501e4bee0f25417ce479
|
data/.gemtest
ADDED
File without changes
|
data/HISTORY.md
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
HISTORY.md
|
2
|
+
Manifest.txt
|
3
|
+
README.md
|
4
|
+
Rakefile
|
5
|
+
lib/beerdb/deleter.rb
|
6
|
+
lib/beerdb/models.rb
|
7
|
+
lib/beerdb/models/beer.rb
|
8
|
+
lib/beerdb/models/brand.rb
|
9
|
+
lib/beerdb/models/brewery.rb
|
10
|
+
lib/beerdb/models/forward.rb
|
11
|
+
lib/beerdb/models/tag.rb
|
12
|
+
lib/beerdb/models/world/city.rb
|
13
|
+
lib/beerdb/models/world/country.rb
|
14
|
+
lib/beerdb/models/world/region.rb
|
15
|
+
lib/beerdb/reader.rb
|
16
|
+
lib/beerdb/reader_file.rb
|
17
|
+
lib/beerdb/reader_zip.rb
|
18
|
+
lib/beerdb/schema.rb
|
19
|
+
lib/beerdb/serializers/beer.rb
|
20
|
+
lib/beerdb/serializers/brewery.rb
|
21
|
+
lib/beerdb/stats.rb
|
22
|
+
lib/beerdb/version.rb
|
23
|
+
test/helper.rb
|
24
|
+
test/test_fixture_matchers.rb
|
25
|
+
test/test_values.rb
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# beerdb-models - beer.db schema 'n' models for easy (re)use
|
2
|
+
|
3
|
+
|
4
|
+
* home :: [github.com/beerkit/beer.db.models](https://github.com/beerkit/beer.db.models)
|
5
|
+
* bugs :: [github.com/beerkit/beer.db.models/issues](https://github.com/beerkit/beer.db.models/issues)
|
6
|
+
* gem :: [rubygems.org/gems/beerdb-models](https://rubygems.org/gems/beerdb-models)
|
7
|
+
* rdoc :: [rubydoc.info/gems/beerdb-models](http://rubydoc.info/gems/beerdb-models)
|
8
|
+
* forum :: [groups.google.com/group/beerdb](https://groups.google.com/group/beerdb)
|
9
|
+
|
10
|
+
|
11
|
+
## Usage Models
|
12
|
+
|
13
|
+
Brewery Model
|
14
|
+
|
15
|
+
```
|
16
|
+
by = Brewery.find_by_key( 'guinness' )
|
17
|
+
|
18
|
+
by.title
|
19
|
+
=> 'St. James's Gate Brewery / Guinness Brewery'
|
20
|
+
|
21
|
+
by.country.key
|
22
|
+
=> 'ie'
|
23
|
+
|
24
|
+
by.country.title
|
25
|
+
=> 'Ireland'
|
26
|
+
|
27
|
+
by.city.title
|
28
|
+
=> 'Dublin'
|
29
|
+
|
30
|
+
by.beers.first
|
31
|
+
=> 'Guinness', 4.2
|
32
|
+
|
33
|
+
...
|
34
|
+
```
|
35
|
+
|
36
|
+
|
37
|
+
Beer Model
|
38
|
+
|
39
|
+
```
|
40
|
+
b = Beer.find_by_key( 'guinness' )
|
41
|
+
|
42
|
+
b.title
|
43
|
+
=> 'Guinness'
|
44
|
+
|
45
|
+
b.abv
|
46
|
+
=> 4.2
|
47
|
+
|
48
|
+
b.tags
|
49
|
+
=> 'irish_dry_stout', 'dry_stout', 'stout'
|
50
|
+
|
51
|
+
b.brewery.title
|
52
|
+
=> 'St. James's Gate Brewery / Guinness Brewery'
|
53
|
+
|
54
|
+
...
|
55
|
+
```
|
56
|
+
|
57
|
+
|
58
|
+
Country Model
|
59
|
+
|
60
|
+
```
|
61
|
+
at = Country.find_by_key( 'at' )
|
62
|
+
|
63
|
+
at.beers
|
64
|
+
=> 'Weitra Helles', 'Hadmar', 'Zwettler Original', ...
|
65
|
+
|
66
|
+
at.breweries
|
67
|
+
=> 'Weitra Bräu Bierwerkstatt', 'Zwettler Brauerei', ...
|
68
|
+
|
69
|
+
...
|
70
|
+
```
|
71
|
+
|
72
|
+
|
73
|
+
City Model
|
74
|
+
|
75
|
+
```
|
76
|
+
wien = City.find_by_key( 'wien' )
|
77
|
+
|
78
|
+
wien.beers
|
79
|
+
=> 'Ottakringer Helles', 'Ottakringer (Gold Fassl) Zwickl', ...
|
80
|
+
|
81
|
+
wien.breweries
|
82
|
+
=> 'Ottakringer Brauerei'
|
83
|
+
|
84
|
+
...
|
85
|
+
```
|
86
|
+
|
87
|
+
|
88
|
+
## License
|
89
|
+
|
90
|
+
The `beerdb-models` scripts are dedicated to the public domain.
|
91
|
+
Use it as you please with no restrictions whatsoever.
|
92
|
+
|
93
|
+
## Questions? Comments?
|
94
|
+
|
95
|
+
Send them along to the [Open Beer & Brewery Database Forum/Mailing List](http://groups.google.com/group/beerdb).
|
96
|
+
Thanks!
|
97
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
require './lib/beerdb/version.rb'
|
3
|
+
|
4
|
+
|
5
|
+
Hoe.spec 'beerdb-models' do
|
6
|
+
|
7
|
+
self.version = BeerDb::VERSION
|
8
|
+
|
9
|
+
self.summary = "beerdb-models - beer.db schema 'n' models for easy (re)use"
|
10
|
+
self.description = summary
|
11
|
+
|
12
|
+
self.urls = ['https://github.com/beerkit/beer.db.models']
|
13
|
+
|
14
|
+
self.author = 'Gerald Bauer'
|
15
|
+
self.email = 'beerdb@googlegroups.com'
|
16
|
+
|
17
|
+
# switch extension to .markdown for gihub formatting
|
18
|
+
self.readme_file = 'README.md'
|
19
|
+
self.history_file = 'HISTORY.md'
|
20
|
+
|
21
|
+
self.extra_deps = [
|
22
|
+
['worlddb-models', '>= 2.2.0'], # Note: worlddb-models pulls in all dependencies
|
23
|
+
]
|
24
|
+
|
25
|
+
self.licenses = ['Public Domain']
|
26
|
+
|
27
|
+
self.spec_extras = {
|
28
|
+
required_ruby_version: '>= 1.9.2'
|
29
|
+
}
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module BeerDb
|
4
|
+
|
5
|
+
class Deleter
|
6
|
+
|
7
|
+
include Models
|
8
|
+
|
9
|
+
def run
|
10
|
+
# for now delete all tables
|
11
|
+
|
12
|
+
### fix: use if defined? BeerDbNote or similar or/and check if table exist ??
|
13
|
+
### or move to beerdb-note ??
|
14
|
+
|
15
|
+
## Bookmark.delete_all # db model extension - move to its own addon?
|
16
|
+
## Drink.delete_all # db model extension - move to its own addon?
|
17
|
+
## Note.delete_all # db model extension - move to its own addon?
|
18
|
+
## User.delete_all # db model extension - move to its own addon?
|
19
|
+
|
20
|
+
Beer.delete_all
|
21
|
+
Brand.delete_all
|
22
|
+
Brewery.delete_all
|
23
|
+
end
|
24
|
+
|
25
|
+
end # class Deleter
|
26
|
+
|
27
|
+
end # module BeerDb
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
require 'worlddb/models' # Note: pull in all required stdlibs n gems via worlddb/models
|
5
|
+
|
6
|
+
|
7
|
+
# our own code
|
8
|
+
|
9
|
+
require 'beerdb/version' ## version always goes first
|
10
|
+
|
11
|
+
require 'beerdb/models/forward'
|
12
|
+
require 'beerdb/models/world/country'
|
13
|
+
require 'beerdb/models/world/region'
|
14
|
+
require 'beerdb/models/world/city'
|
15
|
+
require 'beerdb/models/tag'
|
16
|
+
require 'beerdb/models/beer'
|
17
|
+
require 'beerdb/models/brand'
|
18
|
+
require 'beerdb/models/brewery'
|
19
|
+
|
20
|
+
|
21
|
+
require 'beerdb/serializers/beer'
|
22
|
+
require 'beerdb/serializers/brewery'
|
23
|
+
|
24
|
+
require 'beerdb/schema'
|
25
|
+
require 'beerdb/reader'
|
26
|
+
require 'beerdb/reader_file'
|
27
|
+
require 'beerdb/reader_zip'
|
28
|
+
require 'beerdb/deleter'
|
29
|
+
require 'beerdb/stats'
|
30
|
+
|
31
|
+
|
32
|
+
module BeerDb
|
33
|
+
|
34
|
+
|
35
|
+
def self.create
|
36
|
+
CreateDb.new.up
|
37
|
+
|
38
|
+
### fix: make optional do NOT auto create here
|
39
|
+
### fix: use if defined? BeerDbNote or similar or/and check if table exist ??
|
40
|
+
### or move to beerdb-note ??
|
41
|
+
|
42
|
+
# CreateDbExtrasUsers.new.up
|
43
|
+
# CreateDbExtrasBookmarks.new.up
|
44
|
+
# CreateDbExtrasDrinks.new.up
|
45
|
+
# CreateDbExtrasNotes.new.up
|
46
|
+
|
47
|
+
ConfDb::Model::Prop.create!( key: 'db.schema.beer.version', value: VERSION )
|
48
|
+
end
|
49
|
+
|
50
|
+
## convenience helper for all-in-one create for tables
|
51
|
+
def self.create_all
|
52
|
+
LogDb.create
|
53
|
+
ConfDb.create
|
54
|
+
TagDb.create
|
55
|
+
WorldDb.create
|
56
|
+
BeerDb.create
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def self.read( ary, include_path )
|
61
|
+
reader = Reader.new( include_path )
|
62
|
+
ary.each do |name|
|
63
|
+
reader.load( name )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.read_setup( setup, include_path, opts={} )
|
68
|
+
reader = Reader.new( include_path, opts )
|
69
|
+
reader.load_setup( setup )
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.read_setup_from_zip( zip_name, setup, include_path, opts={} ) ## todo/check - use a better (shorter) name ??
|
73
|
+
reader = ZipReader.new( zip_name, include_path, opts )
|
74
|
+
reader.load_setup( setup )
|
75
|
+
reader.close
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.read_all( include_path, opts={} ) # load all builtins (using plain text reader); helper for convenience
|
79
|
+
read_setup( 'setups/all', include_path, opts )
|
80
|
+
end # method read_all
|
81
|
+
|
82
|
+
|
83
|
+
# delete ALL records (use with care!)
|
84
|
+
def self.delete!
|
85
|
+
puts '*** deleting beer table records/data...'
|
86
|
+
Deleter.new.run
|
87
|
+
end # method delete!
|
88
|
+
|
89
|
+
def self.delete_all!( opts={} )
|
90
|
+
# to be done
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.tables
|
94
|
+
Stats.new.tables
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
end # module BeerDb
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
# say hello
|
103
|
+
puts BeerDb.banner if $DEBUG || (defined?($RUBYLIBS_DEBUG) && $RUBYLIBS_DEBUG)
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module BeerDb
|
4
|
+
module Model
|
5
|
+
|
6
|
+
class Beer < ActiveRecord::Base
|
7
|
+
|
8
|
+
extend TextUtils::TagHelper # will add self.find_tags, self.find_tags_in_attribs!, etc.
|
9
|
+
|
10
|
+
# NB: use extend - is_<type>? become class methods e.g. self.is_<type>? for use in
|
11
|
+
# self.create_or_update_from_values
|
12
|
+
extend TextUtils::ValueHelper # e.g. self.is_year?, self.is_region?, self.is_address?, is_taglist? etc.
|
13
|
+
|
14
|
+
belongs_to :country, :class_name => 'WorldDb::Model::Country', :foreign_key => 'country_id'
|
15
|
+
belongs_to :region, :class_name => 'WorldDb::Model::Region', :foreign_key => 'region_id'
|
16
|
+
belongs_to :city, :class_name => 'WorldDb::Model::City', :foreign_key => 'city_id'
|
17
|
+
|
18
|
+
belongs_to :brand, :class_name => 'BeerDb::Model::Brewery', :foreign_key => 'brand_id'
|
19
|
+
belongs_to :brewery, :class_name => 'BeerDb::Model::Brewery', :foreign_key => 'brewery_id'
|
20
|
+
|
21
|
+
|
22
|
+
has_many :taggings, class_name: 'TagDb::Model::Tagging', :as => :taggable
|
23
|
+
has_many :tags, class_name: 'TagDb::Model::Tag', :through => :taggings
|
24
|
+
|
25
|
+
|
26
|
+
## fix/todo: move to regex to patterns; see worlddb
|
27
|
+
validates :key, :format => { :with => /\A[a-z][a-z0-9]+\z/, :message => 'expected two or more lowercase letters a-z or 0-9 digits' }
|
28
|
+
|
29
|
+
|
30
|
+
########################
|
31
|
+
# begin extras/extension drink/bookmar/user
|
32
|
+
|
33
|
+
has_many :drinks ## :class_name => 'Drink'
|
34
|
+
has_many :notes ## :class_name => 'Note'
|
35
|
+
has_many :bookmarks, :as => :bookmarkable
|
36
|
+
|
37
|
+
# end extensions
|
38
|
+
########
|
39
|
+
|
40
|
+
|
41
|
+
### support old names (read-only) for now (remove later)
|
42
|
+
|
43
|
+
def color() puts "*** depreceated fn api - use srm"; srm; end
|
44
|
+
def plato() puts "*** depreceated fn api - use og"; og; end
|
45
|
+
|
46
|
+
def color=(value)
|
47
|
+
puts "*** depreceated fn api - use srm="
|
48
|
+
self.srm = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def plato=(value)
|
52
|
+
puts "*** depreceated fn api - use og="
|
53
|
+
self.og = value
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def as_json_v2( opts={} )
|
58
|
+
# NB: do NOT overwrite "default" / builtin as_json, thus, lets use as_json_v2
|
59
|
+
BeerSerializer.new( self ).as_json
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def self.create_or_update_from_values( values, more_attribs={} )
|
64
|
+
|
65
|
+
attribs, more_values = find_key_n_title( values )
|
66
|
+
attribs = attribs.merge( more_attribs )
|
67
|
+
|
68
|
+
# check for optional values
|
69
|
+
Beer.create_or_update_from_attribs( attribs, more_values )
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def self.create_or_update_from_attribs( attribs, values )
|
74
|
+
|
75
|
+
# fix: add/configure logger for ActiveRecord!!!
|
76
|
+
logger = LogKernel::Logger.root
|
77
|
+
|
78
|
+
value_tag_keys = []
|
79
|
+
|
80
|
+
## check for grades (e.g. ***/**/*) in titles (will add attribs[:grade] to hash)
|
81
|
+
## if grade missing; set default to 4; lets us update overwrite 1,2,3 values on update
|
82
|
+
attribs[ :grade ] ||= 4
|
83
|
+
|
84
|
+
### check for "default" tags - that is, if present attribs[:tags] remove from hash
|
85
|
+
value_tag_keys += find_tags_in_attribs!( attribs )
|
86
|
+
|
87
|
+
## check for optional values
|
88
|
+
values.each_with_index do |value,index|
|
89
|
+
if match_country(value) do |country|
|
90
|
+
attribs[ :country_id ] = country.id
|
91
|
+
end
|
92
|
+
elsif match_region_for_country(value, attribs[:country_id]) do |region|
|
93
|
+
attribs[ :region_id ] = region.id
|
94
|
+
end
|
95
|
+
elsif match_city(value) do |city|
|
96
|
+
if city.present?
|
97
|
+
attribs[ :city_id ] = city.id
|
98
|
+
else
|
99
|
+
## todo/fix: add strict mode flag - fail w/ exit 1 in strict mode
|
100
|
+
logger.warn "city with key #{value[5..-1]} missing for beer #{attribs[:key]}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
elsif match_brewery(value) do |brewery|
|
104
|
+
attribs[ :brewery_id ] = brewery.id
|
105
|
+
|
106
|
+
# for easy queries cache city and region ids
|
107
|
+
|
108
|
+
# 1) check if brewery has city - if yes, use it for beer too
|
109
|
+
if brewery.city.present?
|
110
|
+
attribs[ :city_id ] = brewery.city.id
|
111
|
+
end
|
112
|
+
|
113
|
+
# 2) check if brewery has city w/ region if yes, use it for beer to
|
114
|
+
# if not check for region for brewery
|
115
|
+
if brewery.city.present? && brewery.city.region.present?
|
116
|
+
attribs[ :region_id ] = brewery.city.region.id
|
117
|
+
elsif brewery.region.present?
|
118
|
+
attribs[ :region_id ] = brewery.region.id
|
119
|
+
end
|
120
|
+
end
|
121
|
+
elsif match_year( value ) do |num| # founded/established year e.g. 1776
|
122
|
+
attribs[ :since ] = num
|
123
|
+
end
|
124
|
+
elsif match_website( value ) do |website| # check for url/internet address e.g. www.ottakringer.at
|
125
|
+
attribs[ :web ] = website
|
126
|
+
end
|
127
|
+
elsif match_abv( value ) do |num| # abv (alcohol by volume)
|
128
|
+
# nb: also allows leading < e.g. <0.5%
|
129
|
+
attribs[ :abv ] = num
|
130
|
+
end
|
131
|
+
elsif match_og( value ) do |num| # plato (stammwuerze/gravity?) e.g. 11.2°
|
132
|
+
# nb: no whitespace allowed between ° and number e.g. 11.2°
|
133
|
+
attribs[ :og ] = num
|
134
|
+
end
|
135
|
+
elsif match_kcal( value ) do |num| # kcal
|
136
|
+
# nb: allow 44.4 kcal/100ml or 44.4 kcal or 44.4kcal
|
137
|
+
attribs[ :kcal ] = num
|
138
|
+
end
|
139
|
+
elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
|
140
|
+
logger.debug " found tags: >>#{value}<<"
|
141
|
+
value_tag_keys += find_tags( value )
|
142
|
+
else
|
143
|
+
# issue warning: unknown type for value
|
144
|
+
logger.warn "unknown type for value >#{value}< - key #{attribs[:key]}"
|
145
|
+
end
|
146
|
+
end # each value
|
147
|
+
|
148
|
+
# rec = Beer.find_by_key_and_country_id( attribs[ :key ], attribs[ :country_id] )
|
149
|
+
rec = Beer.find_by_key( attribs[ :key ] )
|
150
|
+
|
151
|
+
if rec.present?
|
152
|
+
logger.debug "update Beer #{rec.id}-#{rec.key}:"
|
153
|
+
else
|
154
|
+
logger.debug "create Beer:"
|
155
|
+
rec = Beer.new
|
156
|
+
end
|
157
|
+
|
158
|
+
logger.debug attribs.to_json
|
159
|
+
|
160
|
+
rec.update_attributes!( attribs )
|
161
|
+
|
162
|
+
##################
|
163
|
+
# add taggings
|
164
|
+
|
165
|
+
##
|
166
|
+
## fix: delete all tags first or only add diff?
|
167
|
+
## fix e.g.
|
168
|
+
##
|
169
|
+
## [debug] update Beer 1340-opatsvetlevycepni:
|
170
|
+
## [debug] {"title":"Opat Světlé Výčepní","key":"opatsvetlevycepni","country_id":130,"txt":"cz-czech-republic!/beers","grade":4,"brewery_id":839,"city_id":1154,"region_id":241,"abv":4.2,"og":11.0}
|
171
|
+
## [debug] adding 1 taggings: >>pale lager<<...
|
172
|
+
## rake aborted!
|
173
|
+
## ActiveRecord::RecordNotUnique: SQLite3::ConstraintException: columns taggable_id, taggable_type, tag_id are not unique: INSERT INTO "taggings" ("created_at", "tag_id", "taggable_id", "taggable_type", "updated_at") VALUES (?, ?, ?, ?, ?)
|
174
|
+
|
175
|
+
=begin
|
176
|
+
if value_tag_keys.size > 0
|
177
|
+
|
178
|
+
value_tag_keys.uniq! # remove duplicates
|
179
|
+
logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
|
180
|
+
|
181
|
+
### fix/todo: check tag_ids and only update diff (add/remove ids)
|
182
|
+
|
183
|
+
value_tag_keys.each do |key|
|
184
|
+
tag = Tag.find_by_key( key )
|
185
|
+
if tag.nil? # create tag if it doesn't exit
|
186
|
+
logger.debug " creating tag >#{key}<"
|
187
|
+
tag = Tag.create!( key: key )
|
188
|
+
end
|
189
|
+
rec.tags << tag
|
190
|
+
end
|
191
|
+
end
|
192
|
+
=end
|
193
|
+
|
194
|
+
rec # NB: return created or updated obj
|
195
|
+
|
196
|
+
end # method create_or_update_from_values
|
197
|
+
|
198
|
+
end # class Beer
|
199
|
+
|
200
|
+
end # module Model
|
201
|
+
end # module BeerDb
|