Class: WorldDb::Model::StateBase

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

Direct Known Subclasses

County, Muni, Part, State

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TextUtils::ValueHelper

is_state?, match_city, match_country, match_metro, match_metro_flag, match_metro_pop, match_state_for_country, match_supra, match_supra_flag

Class Method Details

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



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
# File 'lib/worlddb/models/state_base.rb', line 90

def self.create_or_update_from_attribs( new_attributes, values, opts={} )

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

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

  value_numbers     = []
  value_tag_keys    = []
  value_cities      = []

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

  ## check for optional values
  values.each_with_index do |value,index|
    if match_country( value ) do |country| # country:
         new_attributes[ :country_id ] = country.id
       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 =~ /#{STATE_CODE_PATTERN}/  ## assume two or 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
        
      ### assume it is the capital city - mark it for auto add
      value_cities << value
      next
 
      # issue warning: unknown type for value
      # logger.warn "unknown type for value >#{value}<"
    end
  end # each value

  if value_numbers.size > 0
    new_attributes[ :area ] = value_numbers[0]
    new_attributes[ :pop  ] = value_numbers[1]
  end  # if value_numbers.size > 0

  ## todo: assert that country_id is present/valid, that is, NOT null
  puts "[debug] StateBase.create_or_update_from_attribs calling #{self.name}.where"  # note: assume self is derived class (object)
  # note: was self.find_by_key_and_country_id
  if self == State
    ## note: state scoped by country (all others by top-level state and NOT country)
    rec = self.find_by(
                  key:         new_attributes[ :key ],
                  country_id:  new_attributes[ :country_id] )
  else
    rec = self.find_by(
                  key:      new_attributes[ :key ],
                  state_id: new_attributes[ :state_id] )
  end

  if rec.present?
    logger.debug "update #{self.name} #{rec.id}-#{rec.key}:"
  else
    logger.debug "create #{self.name}:"    ## e.g. self.name => State, County, Muni, etc.
    puts "[debug] StateBase.create_or_update_from_attribs calling #{self.name}.new"  # note: assume self is derived class (object)
    rec = self.new
  end

  logger.debug new_attributes.to_json

  rec.update_attributes!( new_attributes )

  #################
  # auto add capital cities
  #  - note: get added to top-level state (e.g. adm1)

  City.parse( value_cities,
                 state_id:   rec.state_id,
                 country_id: rec.country_id )  # note: will return an array of (new) city records

  ### todo/fix: add captial ref to country/state
  ## todo/fix: only allow one capital city (now it's an array)


  ##################
  # 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_values(values, more_attribs = {}) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/worlddb/models/state_base.rb', line 76

def self.create_or_update_from_values( values, more_attribs={} )

  ## key & title & country required
  attribs, more_values = find_key_n_title( values )
  ## fix/hack: change :title to :name
  ## attribs[:name] = attribs[:title]; attribs.delete( :title )
  attribs = attribs.merge( more_attribs )

  ## check for optional values
  puts "[debug] StateBase.create_or_update_from_values calling #{self.name}"  # note: assume self is derived class (object)
  self.create_or_update_from_attribs( attribs, more_values )
end

.parse(*args) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/worlddb/models/state_base.rb', line 68

def self.parse( *args )
  ## remove (extract) attribs hash (if last arg is a hash n present)
  more_attribs = args.last.is_a?(Hash) ? args.pop : {}  ## extract_options!
  values       = args

  self.create_or_update_from_values( values, more_attribs )
end

Instance Method Details

#all_names(opts = {}) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/worlddb/models/state_base.rb', line 54

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

#on_createObject

end



32
# File 'lib/worlddb/models/state_base.rb', line 32

before_create :on_create

#on_updateObject



45
46
47
48
49
50
51
# File 'lib/worlddb/models/state_base.rb', line 45

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 )

  ## todo/fix:
  ## update names too ??
end

#synonymsObject



28
# File 'lib/worlddb/models/state_base.rb', line 28

def synonyms()       alt_names;              end

#synonyms=(value) ⇒ Object



29
# File 'lib/worlddb/models/state_base.rb', line 29

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

#titleObject

begin compat



25
# File 'lib/worlddb/models/state_base.rb', line 25

def title()       name;              end

#title=(value) ⇒ Object



26
# File 'lib/worlddb/models/state_base.rb', line 26

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