Class: WorldDb::Model::City

Inherits:
ActiveRecord::Base
  • Object
show all
Extended by:
TextUtils::TagHelper, TextUtils::ValueHelper
Defined in:
lib/worlddb/models/city.rb,
lib/worlddb/models/forward.rb,
lib/worlddb/models/city_comp.rb

Overview

collect depreciated or methods for future removal here

- keep for now for commpatibility (for old code)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create_or_update_from_attribs(new_attributes, values, opts = {}) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/worlddb/models/city.rb', line 130

def self.create_or_update_from_attribs( new_attributes, values, opts={} )
  #   attribs -> key/value pairs e.g. hash
  #   values  -> ary of string values/strings (key not yet known; might be starting of value e.g. city:wien)

  ## opts e.g. :skip_tags true|false

  ## fix: add/configure logger for ActiveRecord!!!
  logger = LogKernel::Logger.root

  value_numbers     = []
  value_tag_keys    = []
    
  ### check for "default" tags - that is, if present new_attributes[:tags] remove from hash
  value_tag_keys += find_tags_in_attribs!( new_attributes )

  new_attributes[ :c ] = true   # assume city type by default (use metro,district to change in fixture)

  ## check for optional values

  values.each_with_index do |value,index|
    if match_region_for_country( value, new_attributes[:country_id] ) do |region|
         new_attributes[ :region_id ] = region.id
       end
    elsif match_country( value ) do |country|
            new_attributes[ :country_id ] = country.id
          end
    elsif match_metro( value ) do |city|
            new_attributes[ :city_id ] = city.id
          end
    elsif match_metro_pop( value ) do |num|  # m:
            new_attributes[ :popm ] = num
            new_attributes[ :m ] = true   #  auto-mark city as m|metro too
          end
    elsif match_metro_flag( value ) do |_|  # metro(politan area)
            new_attributes[ :c ] = false   # turn off default c|city flag; make it m|metro only
            new_attributes[ :m ] = true
          end
    elsif match_city( value ) do |city|  # parent city for district
            new_attributes[ :city_id ] = city.id
            new_attributes[ :c ] = false # turn off default c|city flag; make it d|district only
            new_attributes[ :d ] = true
          end
    elsif match_km_squared( value ) do |num|   # allow numbers like 453 kmĀ²
            value_numbers << num
          end
    elsif match_number( value ) do |num|    # numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
            value_numbers << num
          end
    elsif value =~ /#{CITY_CODE_PATTERN}/  ## assume three-letter code
      new_attributes[ :code ] = value
    elsif (values.size==(index+1)) && is_taglist?( value )   # tags must be last entry
      logger.debug "   found tags: >>#{value}<<"
      value_tag_keys += find_tags( value )
    else
      # issue warning: unknown type for value
      logger.warn "unknown type for value >#{value}<"
    end
  end # each value

  if value_numbers.size > 0
    new_attributes[ :pop  ] = value_numbers[0]   # assume first number is pop for cities
    new_attributes[ :area ] = value_numbers[1]  
  end

  rec = City.find_by_key( new_attributes[ :key ] )

  if rec.present?
    logger.debug "update City #{rec.id}-#{rec.key}:"
  else
    logger.debug "create City:"
    rec = City.new
  end

  logger.debug new_attributes.to_json

  rec.update_attributes!( new_attributes )

    ##################
    ## add taggings

    ## todo/fix: reuse - move add taggings into method etc.

    if value_tag_keys.size > 0

      if opts[:skip_tags].present?
        logger.debug "   skipping add taggings (flag skip_tag)"
      else
        value_tag_keys.uniq!  # remove duplicates
        logger.debug "   adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."

        ### fix/todo: check tag_ids and only update diff (add/remove ids)

        value_tag_keys.each do |key|
          tag = Tag.find_by_key( key )
          if tag.nil?  # create tag if it doesn't exit
            logger.debug "   creating tag >#{key}<"
            tag = Tag.create!( key: key )
          end
          rec.tags << tag
        end
      end
    end

  rec
end

.create_or_update_from_titles(titles, more_attribs = {}) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/worlddb/models/city.rb', line 119

def self.create_or_update_from_titles( titles, more_attribs = {} )
  # ary of titles e.g. ['Wien', 'Graz'] etc.

  titles.each do |title|
    values = [title]
    City.create_or_update_from_values( values, more_attribs ) 
  end # each city
end

.create_or_update_from_values(values, more_attribs = {}) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/worlddb/models/city.rb', line 108

def self.create_or_update_from_values( values, more_attribs={} )
  ## key & title & country required

  attribs, more_values = find_key_n_title( values )
  attribs = attribs.merge( more_attribs )

  ## check for optional values
  City.create_or_update_from_attribs( attribs, more_values )
end

Instance Method Details

#all_names(opts = {}) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/worlddb/models/city.rb', line 94

def all_names( opts={} )
  ### fix:
  ## allow to passing in sep or separator e.g. | or other

  return name if alt_names.blank?
  
  buf = ''
  buf << name
  buf << ' | '
  buf << alt_names.split('|').join(' | ')
  buf
end

#citiesObject

(1) metro - level up



36
# File 'lib/worlddb/models/city.rb', line 36

has_many   :cities,    class_name: 'City',  foreign_key: 'city_id'

#cityObject

(3) district - level down



43
# File 'lib/worlddb/models/city.rb', line 43

belongs_to :city,      class_name: 'City',  foreign_key: 'city_id'

#is_city?Boolean

Returns:

  • (Boolean)


51
# File 'lib/worlddb/models/city.rb', line 51

def is_city?()     c? == true;  end

#is_district?Boolean

Returns:

  • (Boolean)


52
# File 'lib/worlddb/models/city.rb', line 52

def is_district?() d? == true;  end

#is_metro?Boolean

NB: use is_ for flags to avoid conflict w/ assocs (e.g. metro?, city? etc.)

Returns:

  • (Boolean)


50
# File 'lib/worlddb/models/city.rb', line 50

def is_metro?()    m? == true;  end

#metroObject

(2) city



39
# File 'lib/worlddb/models/city.rb', line 39

belongs_to :metro,     class_name: 'City',  foreign_key: 'city_id'

#on_createObject



57
58
59
60
# File 'lib/worlddb/models/city.rb', line 57

def on_create
  place_rec = Place.create!( name: name, kind: place_kind )
  self.place_id = place_rec.id 
end

#on_updateObject



62
63
64
65
# File 'lib/worlddb/models/city.rb', line 62

def on_update
  ## fix/todo: check - if name or kind changed - only update if changed ?? why? why not??
  place.update_attributes!( name: name, kind: place_kind )
end

#place_kindObject

use place_kind_of_code ??



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/worlddb/models/city.rb', line 67

def place_kind   # use place_kind_of_code ??
  ### fix/todo: make sure city records won't overlap (e.g. using metro n city flag at the same time; use separate records)
#//////////////////////////////////
#// fix: add nested record syntax e.g. city w/ metro population
#//  use (metro: 4444)  e.g. must start with (<nested_type>: props) !!! or similar
#//
  if is_metro?
    'MTRO'
  elsif is_district?
    'DIST'
  else
    'CITY'
  end
end

#synonymsObject



18
# File 'lib/worlddb/models/city_comp.rb', line 18

def synonyms()       alt_names;      end

#synonyms=(value) ⇒ Object



19
# File 'lib/worlddb/models/city_comp.rb', line 19

def synonyms=(value) self.alt_names = value; end

#titleObject



12
# File 'lib/worlddb/models/city_comp.rb', line 12

def title()       name;              end

#title=(value) ⇒ Object



13
# File 'lib/worlddb/models/city_comp.rb', line 13

def title=(value) self.name = value; end

#title_w_synonyms(opts = {}) ⇒ Object

depreciated: use all_names instead



21
# File 'lib/worlddb/models/city_comp.rb', line 21

def title_w_synonyms( opts={} )  all_names( opts );  end