migrate with countries_states_cities_db
This commit is contained in:
parent
6281ca73a2
commit
652107d0ee
@ -41,12 +41,12 @@ ActiveAdmin.register_page "Ahoy Dashboard" do
|
||||
column do
|
||||
panel "最冷门活跃城市" do
|
||||
# table_for City.least_popular_active.limit(10) do
|
||||
table_for City.least_popular_active do
|
||||
table_for City.least_popular_active.limit(100) do
|
||||
column("ID") { |city| city.id }
|
||||
column("城市") { |city| link_to(city.name, admin_city_path(city)) }
|
||||
column("访问(DWMY)") { |city| "#{city.view_count(:day)}/#{city.view_count(:week)}/#{city.view_count(:month)}/#{city.view_count(:year)}" }
|
||||
column("状态") { |city| status_tag(city.active? ? "活跃" : "停用") }
|
||||
column("所属区域") { |city| city.country.name+"/"+city.country.region.name }
|
||||
column("所属区域") { |city| city&.country&.name.to_s+"/"+city&.country&.region&.name.to_s }
|
||||
column("图像个数") { |city| city.weather_arts.count }
|
||||
column("最后更新时间") { |city| city.last_weather_fetch }
|
||||
# column("状态") { |city| status_tag(city.active? ? "活跃" : "停用") }
|
||||
@ -63,12 +63,12 @@ ActiveAdmin.register_page "Ahoy Dashboard" do
|
||||
column do
|
||||
panel "热门未活跃城市" do
|
||||
# table_for City.most_popular_inactive.limit(10) do
|
||||
table_for City.most_popular_inactive do
|
||||
table_for City.most_popular_inactive(100) do
|
||||
column("ID") { |city| city.id }
|
||||
column("城市") { |city| link_to(city.name, admin_city_path(city)) }
|
||||
column("访问(DWMY)") { |city| "#{city.view_count(:day)}/#{city.view_count(:week)}/#{city.view_count(:month)}/#{city.view_count(:year)}" }
|
||||
column("状态") { |city| status_tag(city.active? ? "活跃" : "停用") }
|
||||
column("所属区域") { |city| city.country.name+"/"+city.country.region.name }
|
||||
column("所属区域") { |city| city&.country&.name.to_s+"/"+city.country&.region&.name.to_s }
|
||||
column("图像个数") { |city| city.weather_arts.count }
|
||||
column("最后更新时间") { |city| city.last_weather_fetch }
|
||||
column("操作") { |city|
|
||||
|
@ -16,6 +16,6 @@ class ArtsController < ApplicationController
|
||||
@weather_arts.order(created_at: :desc)
|
||||
end
|
||||
|
||||
@weather_arts = @weather_arts.page(params[:page]).per(10)
|
||||
@weather_arts = @weather_arts.page(params[:page]).per(12)
|
||||
end
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ class CitiesController < ApplicationController
|
||||
|
||||
if params[:region]
|
||||
@current_region = Region.friendly.find(params[:region])
|
||||
@cities = @cities.by_region(@current_region.id)
|
||||
@cities = @cities.by_region(@current_region.id) if @current_region
|
||||
end
|
||||
|
||||
if params[:country]
|
||||
@ -13,7 +13,7 @@ class CitiesController < ApplicationController
|
||||
@cities = @cities.by_country(@current_country.id)
|
||||
end
|
||||
|
||||
@cities = @cities.page(params[:page]).per(10)
|
||||
@cities = @cities.page(params[:page]).per(12)
|
||||
|
||||
set_meta_tags(
|
||||
title: @current_region ? "Cities in #{@current_region.name}" : "Explore Cities",
|
||||
|
@ -2,6 +2,7 @@ class City < ApplicationRecord
|
||||
extend FriendlyId
|
||||
friendly_id :slug_candidates, use: :slugged
|
||||
belongs_to :country
|
||||
belongs_to :state, optional: true
|
||||
|
||||
has_many :weather_arts, dependent: :destroy
|
||||
|
||||
@ -37,38 +38,38 @@ class City < ApplicationRecord
|
||||
end
|
||||
}
|
||||
|
||||
scope :least_popular_active, -> {
|
||||
scope :least_popular_active, ->(limit = 100) {
|
||||
if ActiveRecord::Base.connection.adapter_name.downcase == "sqlite"
|
||||
active
|
||||
.joins("LEFT JOIN ahoy_events ON json_extract(ahoy_events.properties, '$.city_id') = cities.id
|
||||
AND json_extract(ahoy_events.properties, '$.event_type') = 'city_view'")
|
||||
.group("cities.id")
|
||||
.select("cities.*, COUNT(ahoy_events.id) as visit_count")
|
||||
.order("visit_count ASC, cities.name ASC")
|
||||
.order("visit_count ASC, cities.name ASC").limit(limit)
|
||||
else
|
||||
active
|
||||
.joins("LEFT JOIN ahoy_events ON (ahoy_events.properties::jsonb->>'city_id')::integer = cities.id
|
||||
AND ahoy_events.properties::jsonb->>'event_type' = 'city_view'")
|
||||
.group("cities.id")
|
||||
.select("cities.*, COUNT(ahoy_events.id) as visit_count")
|
||||
.order("visit_count ASC, cities.name ASC")
|
||||
.order("visit_count ASC, cities.name ASC").limit(limit)
|
||||
end
|
||||
}
|
||||
scope :most_popular_inactive, -> {
|
||||
scope :most_popular_inactive, ->(limit = 100) {
|
||||
if ActiveRecord::Base.connection.adapter_name.downcase == "sqlite"
|
||||
where(active: false)
|
||||
.joins("LEFT JOIN ahoy_events ON json_extract(ahoy_events.properties, '$.city_id') = cities.id
|
||||
AND json_extract(ahoy_events.properties, '$.event_type') = 'city_view'")
|
||||
.group("cities.id")
|
||||
.select("cities.*, COUNT(ahoy_events.id) as visit_count")
|
||||
.order("COUNT(ahoy_events.id) DESC, cities.name ASC")
|
||||
.order("COUNT(ahoy_events.id) DESC, cities.name ASC").limit(limit)
|
||||
else
|
||||
where(active: false)
|
||||
.joins("LEFT JOIN ahoy_events ON (ahoy_events.properties::jsonb->>'city_id')::integer = cities.id
|
||||
AND ahoy_events.properties::jsonb->>'event_type' = 'city_view'")
|
||||
.group("cities.id")
|
||||
.select("cities.*, COUNT(ahoy_events.id) as visit_count")
|
||||
.order("COUNT(ahoy_events.id) DESC, cities.name ASC")
|
||||
.order("COUNT(ahoy_events.id) DESC, cities.name ASC").limit(limit)
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,14 @@ class Country < ApplicationRecord
|
||||
extend FriendlyId
|
||||
friendly_id :name, use: :slugged
|
||||
|
||||
belongs_to :region
|
||||
belongs_to :region, optional: true
|
||||
belongs_to :subregion, optional: true
|
||||
has_many :cities, dependent: :restrict_with_error
|
||||
has_many :states
|
||||
|
||||
validates :name, presence: true
|
||||
validates :code, presence: true, uniqueness: true
|
||||
validates :iso2, uniqueness: true, allow_blank: true
|
||||
|
||||
def to_s
|
||||
name
|
||||
|
@ -4,8 +4,9 @@ class Region < ApplicationRecord
|
||||
|
||||
has_many :countries, dependent: :restrict_with_error
|
||||
has_many :cities, through: :countries
|
||||
has_many :subregions
|
||||
|
||||
validates :name, presence: true
|
||||
validates :name, presence: true, uniqueness: true
|
||||
validates :code, presence: true, uniqueness: true
|
||||
|
||||
def to_s
|
||||
|
7
app/models/state.rb
Normal file
7
app/models/state.rb
Normal file
@ -0,0 +1,7 @@
|
||||
class State < ApplicationRecord
|
||||
belongs_to :country
|
||||
has_many :cities
|
||||
|
||||
validates :name, presence: true
|
||||
validates :country_code, presence: true
|
||||
end
|
6
app/models/subregion.rb
Normal file
6
app/models/subregion.rb
Normal file
@ -0,0 +1,6 @@
|
||||
class Subregion < ApplicationRecord
|
||||
belongs_to :region
|
||||
has_many :countries
|
||||
|
||||
validates :name, presence: true
|
||||
end
|
@ -32,7 +32,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
</svg>
|
||||
<%= city.country.name %>, <%= city.region.name %>
|
||||
<%= city&.country&.name %>, <%= city&.region&.name %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -92,7 +92,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
</svg>
|
||||
<%= city.country.name %>, <%= city.region.name %>
|
||||
<%= city&.country&.name %>, <%= city&.region&.name %>
|
||||
</div>
|
||||
|
||||
<div class="bg-base-200 rounded-lg p-4 mb-4">
|
||||
|
@ -51,7 +51,7 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
<ul class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52">
|
||||
<ul class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52 max-h-80 overflow-y-auto flex-nowrap">
|
||||
<li>
|
||||
<%= link_to cities_path,
|
||||
class: "#{@current_region ? '' : 'active'}" do %>
|
||||
@ -70,7 +70,7 @@
|
||||
</div>
|
||||
|
||||
<% if @current_region %>
|
||||
<div class="dropdown">
|
||||
<div class="dropdown dropdown-bottom">
|
||||
<button class="btn btn-ghost gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 21v-4m0 0V5a2 2 0 012-2h6.5l1 1H21l-3 6 3 6h-8.5l-1-1H5a2 2 0 00-2 2zm9-13.5V9" />
|
||||
@ -80,7 +80,7 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
<ul class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52">
|
||||
<ul class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52 max-h-80 overflow-y-auto flex-nowrap">
|
||||
<li>
|
||||
<%= link_to "All in #{@current_region.name}",
|
||||
cities_path(region: @current_region.slug),
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="join shadow-lg">
|
||||
<!-- 首页 -->
|
||||
<%= link_to url_for(page: 1, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs #{collection.first_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
class: "join-item btn btn-sm #{collection.first_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
|
||||
</svg>
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
<!-- 上一页 -->
|
||||
<%= link_to url_for(page: collection.prev_page || 1, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs #{collection.first_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
class: "join-item btn btn-sm #{collection.first_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
@ -33,35 +33,35 @@
|
||||
|
||||
<% if start_page > 1 %>
|
||||
<%= link_to 1, url_for(page: 1, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs btn-ghost hover:bg-primary/5" %>
|
||||
class: "join-item btn btn-sm btn-ghost hover:bg-primary/5" %>
|
||||
<% if start_page > 2 %>
|
||||
<button class="join-item btn btn-xs btn-ghost btn-disabled">...</button>
|
||||
<button class="join-item btn btn-sm btn-ghost btn-disabled">...</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% (start_page..end_page).each do |page| %>
|
||||
<% if page == collection.current_page %>
|
||||
<button class="join-item btn btn-xs btn-ghost bg-primary/10 font-medium">
|
||||
<button class="join-item btn btn-sm btn-ghost bg-primary/10 font-medium">
|
||||
<%= page %>
|
||||
</button>
|
||||
<% else %>
|
||||
<%= link_to page, url_for(page: page, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs btn-ghost hover:bg-primary/5" %>
|
||||
class: "join-item btn btn-sm btn-ghost hover:bg-primary/5" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if end_page < collection.total_pages %>
|
||||
<% if end_page < collection.total_pages - 1 %>
|
||||
<button class="join-item btn btn-xs btn-ghost btn-disabled">...</button>
|
||||
<button class="join-item btn btn-sm btn-ghost btn-disabled">...</button>
|
||||
<% end %>
|
||||
<%= link_to collection.total_pages,
|
||||
url_for(page: collection.total_pages, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs btn-ghost hover:bg-primary/5" %>
|
||||
class: "join-item btn btn-sm btn-ghost hover:bg-primary/5" %>
|
||||
<% end %>
|
||||
|
||||
<!-- 下一页 -->
|
||||
<%= link_to url_for(page: collection.next_page || collection.total_pages, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs #{collection.last_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
class: "join-item btn btn-sm #{collection.last_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
@ -69,7 +69,7 @@
|
||||
|
||||
<!-- 末页 -->
|
||||
<%= link_to url_for(page: collection.total_pages, region: params[:region], country: params[:country], sort: params[:sort]),
|
||||
class: "join-item btn btn-xs #{collection.last_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
class: "join-item btn btn-sm #{collection.last_page? ? 'btn-disabled' : 'btn-ghost'}" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 5l7 7-7 7M5 5l7 7-7 7" />
|
||||
</svg>
|
||||
|
@ -1,5 +1,5 @@
|
||||
batch_generate_weather:
|
||||
cron: '0 */1 * * *'
|
||||
cron: '0 8,18 * * *'
|
||||
class: BatchGenerateWeatherArtsWorker
|
||||
description: "Generate weather arts every 2 hours"
|
||||
enabled: true
|
||||
|
@ -0,0 +1,36 @@
|
||||
class MigrateWithCountriesStatesCitiesDatabase < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :regions, :translations, :text, if_not_exists: true
|
||||
add_column :regions, :flag, :boolean, default: true, if_not_exists: true
|
||||
add_column :regions, :wiki_data_id, :string, if_not_exists: true
|
||||
|
||||
add_column :countries, :iso3, :string
|
||||
add_column :countries, :numeric_code, :string
|
||||
add_column :countries, :iso2, :string
|
||||
add_column :countries, :phonecode, :string
|
||||
add_column :countries, :capital, :string
|
||||
add_column :countries, :currency, :string
|
||||
add_column :countries, :currency_name, :string
|
||||
add_column :countries, :currency_symbol, :string
|
||||
add_column :countries, :tld, :string
|
||||
add_column :countries, :native, :string
|
||||
add_column :countries, :region, :string
|
||||
add_column :countries, :subregion, :string
|
||||
add_column :countries, :nationality, :string
|
||||
add_column :countries, :timezones, :text
|
||||
add_column :countries, :translations, :text
|
||||
add_column :countries, :latitude, :decimal, precision: 10, scale: 8
|
||||
add_column :countries, :longitude, :decimal, precision: 11, scale: 8
|
||||
add_column :countries, :emoji, :string
|
||||
add_column :countries, :emoji_u, :string
|
||||
add_column :countries, :flag, :boolean, default: true
|
||||
add_column :countries, :wiki_data_id, :string
|
||||
add_reference :countries, :region, foreign_key: true
|
||||
|
||||
add_column :cities, :state_code, :string
|
||||
add_column :cities, :country_code, :string
|
||||
add_column :cities, :flag, :boolean, default: true
|
||||
add_column :cities, :wiki_data_id, :string
|
||||
add_column :cities, :active, :boolean, default: false
|
||||
end
|
||||
end
|
22
db/migrate/20250208052549_create_states.rb
Normal file
22
db/migrate/20250208052549_create_states.rb
Normal file
@ -0,0 +1,22 @@
|
||||
class CreateStates < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :states do |t|
|
||||
t.string :name
|
||||
t.string :code
|
||||
t.references :country, foreign_key: true
|
||||
t.string :country_code
|
||||
t.string :fips_code
|
||||
t.string :iso2
|
||||
t.string :state_type
|
||||
t.integer :level
|
||||
t.integer :parent_id
|
||||
t.decimal :latitude, precision: 10, scale: 8
|
||||
t.decimal :longitude, precision: 11, scale: 8
|
||||
t.boolean :flag
|
||||
t.string :wiki_data_id
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_reference :cities, :state, foreign_key: true
|
||||
end
|
||||
end
|
15
db/migrate/20250208052634_create_subregions.rb
Normal file
15
db/migrate/20250208052634_create_subregions.rb
Normal file
@ -0,0 +1,15 @@
|
||||
class CreateSubregions < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :subregions do |t|
|
||||
t.string :name, null: false
|
||||
t.text :translations
|
||||
t.references :region, foreign_key: true, null: false
|
||||
t.boolean :flag, default: true
|
||||
t.string :wiki_data_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_reference :countries, :subregion, foreign_key: true, null: true
|
||||
end
|
||||
end
|
84
db/schema.rb
generated
84
db/schema.rb
generated
@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_01_26_155239) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_02_08_052634) do
|
||||
create_table "active_admin_comments", force: :cascade do |t|
|
||||
t.string "namespace"
|
||||
t.text "body"
|
||||
@ -111,27 +111,57 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_26_155239) do
|
||||
t.string "name"
|
||||
t.float "latitude"
|
||||
t.float "longitude"
|
||||
t.boolean "active"
|
||||
t.integer "priority"
|
||||
t.string "timezone"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "slug"
|
||||
t.integer "country_id", null: false
|
||||
t.string "state_code"
|
||||
t.string "country_code"
|
||||
t.boolean "flag", default: true
|
||||
t.string "wiki_data_id"
|
||||
t.boolean "active", default: false
|
||||
t.integer "state_id"
|
||||
t.index ["country_id"], name: "index_cities_on_country_id"
|
||||
t.index ["slug"], name: "index_cities_on_slug", unique: true
|
||||
t.index ["state_id"], name: "index_cities_on_state_id"
|
||||
end
|
||||
|
||||
create_table "countries", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "code"
|
||||
t.string "slug"
|
||||
t.integer "region_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "emojiU"
|
||||
t.string "iso3"
|
||||
t.string "numeric_code"
|
||||
t.string "iso2"
|
||||
t.string "phonecode"
|
||||
t.string "capital"
|
||||
t.string "currency"
|
||||
t.string "currency_name"
|
||||
t.string "currency_symbol"
|
||||
t.string "tld"
|
||||
t.string "native"
|
||||
t.string "region"
|
||||
t.string "subregion"
|
||||
t.string "nationality"
|
||||
t.text "timezones"
|
||||
t.text "translations"
|
||||
t.decimal "latitude", precision: 10, scale: 8
|
||||
t.decimal "longitude", precision: 11, scale: 8
|
||||
t.string "emoji"
|
||||
t.string "emoji_u"
|
||||
t.boolean "flag", default: true
|
||||
t.string "wiki_data_id"
|
||||
t.integer "region_id"
|
||||
t.integer "subregion_id"
|
||||
t.index ["code"], name: "index_countries_on_code", unique: true
|
||||
t.index ["region_id"], name: "index_countries_on_region_id"
|
||||
t.index ["slug"], name: "index_countries_on_slug", unique: true
|
||||
t.index ["subregion_id"], name: "index_countries_on_subregion_id"
|
||||
end
|
||||
|
||||
create_table "friendly_id_slugs", force: :cascade do |t|
|
||||
@ -151,10 +181,54 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_26_155239) do
|
||||
t.string "slug"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "translations"
|
||||
t.boolean "flag", default: true
|
||||
t.string "wiki_data_id"
|
||||
t.index ["code"], name: "index_regions_on_code", unique: true
|
||||
t.index ["slug"], name: "index_regions_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "states", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "code"
|
||||
t.integer "country_id"
|
||||
t.string "country_code"
|
||||
t.string "fips_code"
|
||||
t.string "iso2"
|
||||
t.string "state_type"
|
||||
t.integer "level"
|
||||
t.integer "parent_id"
|
||||
t.decimal "latitude", precision: 10, scale: 8
|
||||
t.decimal "longitude", precision: 11, scale: 8
|
||||
t.boolean "flag"
|
||||
t.string "wiki_data_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["country_id"], name: "index_states_on_country_id"
|
||||
end
|
||||
|
||||
create_table "subregions", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.text "translations"
|
||||
t.integer "region_id", null: false
|
||||
t.boolean "flag", default: true
|
||||
t.string "wiki_data_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["region_id"], name: "index_subregions_on_region_id"
|
||||
end
|
||||
|
||||
create_table "votes", force: :cascade do |t|
|
||||
t.string "votable_type"
|
||||
t.integer "votable_id"
|
||||
t.string "session_id"
|
||||
t.integer "vote_type", default: 0
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["votable_id", "votable_type", "session_id", "vote_type"], name: "index_votes_on_votable_and_session_id_and_vote_type", unique: true
|
||||
t.index ["votable_type", "votable_id"], name: "index_votes_on_votable"
|
||||
end
|
||||
|
||||
create_table "weather_arts", force: :cascade do |t|
|
||||
t.integer "city_id", null: false
|
||||
t.date "weather_date"
|
||||
@ -180,6 +254,10 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_26_155239) do
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "cities", "countries"
|
||||
add_foreign_key "cities", "states"
|
||||
add_foreign_key "countries", "regions"
|
||||
add_foreign_key "countries", "subregions"
|
||||
add_foreign_key "states", "countries"
|
||||
add_foreign_key "subregions", "regions"
|
||||
add_foreign_key "weather_arts", "cities"
|
||||
end
|
||||
|
1963314
lib/data/cities.json
Normal file
1963314
lib/data/cities.json
Normal file
File diff suppressed because it is too large
Load Diff
13726
lib/data/countries.json
Normal file
13726
lib/data/countries.json
Normal file
File diff suppressed because it is too large
Load Diff
140
lib/data/regions.json
Normal file
140
lib/data/regions.json
Normal file
@ -0,0 +1,140 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Africa",
|
||||
"translations": {
|
||||
"ko": "아프리카",
|
||||
"pt-BR": "África",
|
||||
"pt": "África",
|
||||
"nl": "Afrika",
|
||||
"hr": "Afrika",
|
||||
"fa": "آفریقا",
|
||||
"de": "Afrika",
|
||||
"es": "África",
|
||||
"fr": "Afrique",
|
||||
"ja": "アフリカ",
|
||||
"it": "Africa",
|
||||
"zh-CN": "非洲",
|
||||
"tr": "Afrika",
|
||||
"ru": "Африка",
|
||||
"uk": "Африка",
|
||||
"pl": "Afryka"
|
||||
},
|
||||
"wikiDataId": "Q15"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Americas",
|
||||
"translations": {
|
||||
"ko": "아메리카",
|
||||
"pt-BR": "América",
|
||||
"pt": "América",
|
||||
"nl": "Amerika",
|
||||
"hr": "Amerika",
|
||||
"fa": "قاره آمریکا",
|
||||
"de": "Amerika",
|
||||
"es": "América",
|
||||
"fr": "Amérique",
|
||||
"ja": "アメリカ州",
|
||||
"it": "America",
|
||||
"zh-CN": "美洲",
|
||||
"tr": "Amerika",
|
||||
"ru": "Америка",
|
||||
"uk": "Америка",
|
||||
"pl": "Ameryka"
|
||||
},
|
||||
"wikiDataId": "Q828"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Asia",
|
||||
"translations": {
|
||||
"ko": "아시아",
|
||||
"pt-BR": "Ásia",
|
||||
"pt": "Ásia",
|
||||
"nl": "Azië",
|
||||
"hr": "Ázsia",
|
||||
"fa": "آسیا",
|
||||
"de": "Asien",
|
||||
"es": "Asia",
|
||||
"fr": "Asie",
|
||||
"ja": "アジア",
|
||||
"it": "Asia",
|
||||
"zh-CN": "亚洲",
|
||||
"tr": "Asya",
|
||||
"ru": "Азия",
|
||||
"uk": "Азія",
|
||||
"pl": "Azja"
|
||||
},
|
||||
"wikiDataId": "Q48"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Europe",
|
||||
"translations": {
|
||||
"ko": "유럽",
|
||||
"pt-BR": "Europa",
|
||||
"pt": "Europa",
|
||||
"nl": "Europa",
|
||||
"hr": "Európa",
|
||||
"fa": "اروپا",
|
||||
"de": "Europa",
|
||||
"es": "Europa",
|
||||
"fr": "Europe",
|
||||
"ja": "ヨーロッパ",
|
||||
"it": "Europa",
|
||||
"zh-CN": "欧洲",
|
||||
"tr": "Avrupa",
|
||||
"ru": "Европа",
|
||||
"uk": "Європа",
|
||||
"pl": "Europa"
|
||||
},
|
||||
"wikiDataId": "Q46"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Oceania",
|
||||
"translations": {
|
||||
"ko": "오세아니아",
|
||||
"pt-BR": "Oceania",
|
||||
"pt": "Oceania",
|
||||
"nl": "Oceanië en Australië",
|
||||
"hr": "Óceánia és Ausztrália",
|
||||
"fa": "اقیانوسیه",
|
||||
"de": "Ozeanien und Australien",
|
||||
"es": "Oceanía",
|
||||
"fr": "Océanie",
|
||||
"ja": "オセアニア",
|
||||
"it": "Oceania",
|
||||
"zh-CN": "大洋洲",
|
||||
"tr": "Okyanusya",
|
||||
"ru": "Океания",
|
||||
"uk": "Океанія",
|
||||
"pl": "Oceania"
|
||||
},
|
||||
"wikiDataId": "Q55643"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Polar",
|
||||
"translations": {
|
||||
"ko": "남극",
|
||||
"pt-BR": "Antártida",
|
||||
"pt": "Antártida",
|
||||
"nl": "Antarctica",
|
||||
"hr": "Antarktika",
|
||||
"fa": "جنوبگان",
|
||||
"de": "Antarktika",
|
||||
"es": "Antártida",
|
||||
"fr": "Antarctique",
|
||||
"ja": "南極大陸",
|
||||
"it": "Antartide",
|
||||
"zh-CN": "南極洲",
|
||||
"tr": "Antarktika",
|
||||
"ru": "Антарктика",
|
||||
"uk": "Антарктика",
|
||||
"pl": "Antarktyka"
|
||||
},
|
||||
"wikiDataId": "Q51"
|
||||
}
|
||||
]
|
55420
lib/data/states.json
Normal file
55420
lib/data/states.json
Normal file
File diff suppressed because it is too large
Load Diff
485
lib/data/subregions.json
Normal file
485
lib/data/subregions.json
Normal file
@ -0,0 +1,485 @@
|
||||
[
|
||||
{
|
||||
"id": 19,
|
||||
"name": "Australia and New Zealand",
|
||||
"region_id": "5",
|
||||
"translations": {
|
||||
"ko": "오스트랄라시아",
|
||||
"pt": "Australásia",
|
||||
"nl": "Australazië",
|
||||
"hr": "Australazija",
|
||||
"fa": "استرالزی",
|
||||
"de": "Australasien",
|
||||
"es": "Australasia",
|
||||
"fr": "Australasie",
|
||||
"ja": "オーストララシア",
|
||||
"it": "Australasia",
|
||||
"zh-CN": "澳大拉西亞",
|
||||
"ru": "Австралия и Новая Зеландия",
|
||||
"uk": "Австралія та Нова Зеландія",
|
||||
"pl": "Australia i Nowa Zelandia"
|
||||
},
|
||||
"wikiDataId": "Q45256"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Caribbean",
|
||||
"region_id": "2",
|
||||
"translations": {
|
||||
"ko": "카리브",
|
||||
"pt": "Caraíbas",
|
||||
"nl": "Caraïben",
|
||||
"hr": "Karibi",
|
||||
"fa": "کارائیب",
|
||||
"de": "Karibik",
|
||||
"es": "Caribe",
|
||||
"fr": "Caraïbes",
|
||||
"ja": "カリブ海地域",
|
||||
"it": "Caraibi",
|
||||
"zh-CN": "加勒比地区",
|
||||
"ru": "Карибы",
|
||||
"uk": "Кариби",
|
||||
"pl": "Karaiby"
|
||||
},
|
||||
"wikiDataId": "Q664609"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Central America",
|
||||
"region_id": "2",
|
||||
"translations": {
|
||||
"ko": "중앙아메리카",
|
||||
"pt": "América Central",
|
||||
"nl": "Centraal-Amerika",
|
||||
"hr": "Srednja Amerika",
|
||||
"fa": "آمریکای مرکزی",
|
||||
"de": "Zentralamerika",
|
||||
"es": "América Central",
|
||||
"fr": "Amérique centrale",
|
||||
"ja": "中央アメリカ",
|
||||
"it": "America centrale",
|
||||
"zh-CN": "中美洲",
|
||||
"ru": "Центральная Америка",
|
||||
"uk": "Центральна Америка",
|
||||
"pl": "Ameryka Środkowa"
|
||||
},
|
||||
"wikiDataId": "Q27611"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Central Asia",
|
||||
"region_id": "3",
|
||||
"translations": {
|
||||
"ko": "중앙아시아",
|
||||
"pt": "Ásia Central",
|
||||
"nl": "Centraal-Azië",
|
||||
"hr": "Srednja Azija",
|
||||
"fa": "آسیای میانه",
|
||||
"de": "Zentralasien",
|
||||
"es": "Asia Central",
|
||||
"fr": "Asie centrale",
|
||||
"ja": "中央アジア",
|
||||
"it": "Asia centrale",
|
||||
"zh-CN": "中亚",
|
||||
"ru": "Центральная Азия",
|
||||
"uk": "Центральна Азія",
|
||||
"pl": "Azja Środkowa"
|
||||
},
|
||||
"wikiDataId": "Q27275"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Eastern Africa",
|
||||
"region_id": "1",
|
||||
"translations": {
|
||||
"ko": "동아프리카",
|
||||
"pt": "África Oriental",
|
||||
"nl": "Oost-Afrika",
|
||||
"hr": "Istočna Afrika",
|
||||
"fa": "شرق آفریقا",
|
||||
"de": "Ostafrika",
|
||||
"es": "África Oriental",
|
||||
"fr": "Afrique de l'Est",
|
||||
"ja": "東アフリカ",
|
||||
"it": "Africa orientale",
|
||||
"zh-CN": "东部非洲",
|
||||
"ru": "Восточная Африка",
|
||||
"uk": "Східна Африка",
|
||||
"pl": "Afryka Wschodnia"
|
||||
},
|
||||
"wikiDataId": "Q27407"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "Eastern Asia",
|
||||
"region_id": "3",
|
||||
"translations": {
|
||||
"ko": "동아시아",
|
||||
"pt": "Ásia Oriental",
|
||||
"nl": "Oost-Azië",
|
||||
"hr": "Istočna Azija",
|
||||
"fa": "شرق آسیا",
|
||||
"de": "Ostasien",
|
||||
"es": "Asia Oriental",
|
||||
"fr": "Asie de l'Est",
|
||||
"ja": "東アジア",
|
||||
"it": "Asia orientale",
|
||||
"zh-CN": "東亞",
|
||||
"ru": "Восточная Азия",
|
||||
"uk": "Східна Азія",
|
||||
"pl": "Azja Wschodnia"
|
||||
},
|
||||
"wikiDataId": "Q27231"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Eastern Europe",
|
||||
"region_id": "4",
|
||||
"translations": {
|
||||
"ko": "동유럽",
|
||||
"pt": "Europa de Leste",
|
||||
"nl": "Oost-Europa",
|
||||
"hr": "Istočna Europa",
|
||||
"fa": "شرق اروپا",
|
||||
"de": "Osteuropa",
|
||||
"es": "Europa Oriental",
|
||||
"fr": "Europe de l'Est",
|
||||
"ja": "東ヨーロッパ",
|
||||
"it": "Europa orientale",
|
||||
"zh-CN": "东欧",
|
||||
"ru": "Восточная Европа",
|
||||
"uk": "Східна Європа",
|
||||
"pl": "Europa Wschodnia"
|
||||
},
|
||||
"wikiDataId": "Q27468"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "Melanesia",
|
||||
"region_id": "5",
|
||||
"translations": {
|
||||
"ko": "멜라네시아",
|
||||
"pt": "Melanésia",
|
||||
"nl": "Melanesië",
|
||||
"hr": "Melanezija",
|
||||
"fa": "ملانزی",
|
||||
"de": "Melanesien",
|
||||
"es": "Melanesia",
|
||||
"fr": "Mélanésie",
|
||||
"ja": "メラネシア",
|
||||
"it": "Melanesia",
|
||||
"zh-CN": "美拉尼西亚",
|
||||
"ru": "Меланезия",
|
||||
"uk": "Меланезія",
|
||||
"pl": "Melanezja"
|
||||
},
|
||||
"wikiDataId": "Q37394"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "Micronesia",
|
||||
"region_id": "5",
|
||||
"translations": {
|
||||
"ko": "미크로네시아",
|
||||
"pt": "Micronésia",
|
||||
"nl": "Micronesië",
|
||||
"hr": "Mikronezija",
|
||||
"fa": "میکرونزی",
|
||||
"de": "Mikronesien",
|
||||
"es": "Micronesia",
|
||||
"fr": "Micronésie",
|
||||
"ja": "ミクロネシア",
|
||||
"it": "Micronesia",
|
||||
"zh-CN": "密克罗尼西亚群岛",
|
||||
"ru": "Микронезия",
|
||||
"uk": "Мікронезія",
|
||||
"pl": "Mikronezja"
|
||||
},
|
||||
"wikiDataId": "Q3359409"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Middle Africa",
|
||||
"region_id": "1",
|
||||
"translations": {
|
||||
"ko": "중앙아프리카",
|
||||
"pt": "África Central",
|
||||
"nl": "Centraal-Afrika",
|
||||
"hr": "Srednja Afrika",
|
||||
"fa": "مرکز آفریقا",
|
||||
"de": "Zentralafrika",
|
||||
"es": "África Central",
|
||||
"fr": "Afrique centrale",
|
||||
"ja": "中部アフリカ",
|
||||
"it": "Africa centrale",
|
||||
"zh-CN": "中部非洲",
|
||||
"ru": "Средняя Африка",
|
||||
"uk": "Середня Африка",
|
||||
"pl": "Afryka Środkowa"
|
||||
},
|
||||
"wikiDataId": "Q27433"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Northern Africa",
|
||||
"region_id": "1",
|
||||
"translations": {
|
||||
"ko": "북아프리카",
|
||||
"pt": "Norte de África",
|
||||
"nl": "Noord-Afrika",
|
||||
"hr": "Sjeverna Afrika",
|
||||
"fa": "شمال آفریقا",
|
||||
"de": "Nordafrika",
|
||||
"es": "Norte de África",
|
||||
"fr": "Afrique du Nord",
|
||||
"ja": "北アフリカ",
|
||||
"it": "Nordafrica",
|
||||
"zh-CN": "北部非洲",
|
||||
"ru": "Северная Африка",
|
||||
"uk": "Північна Африка",
|
||||
"pl": "Afryka Północna"
|
||||
},
|
||||
"wikiDataId": "Q27381"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Northern America",
|
||||
"region_id": "2",
|
||||
"translations": {
|
||||
"ko": "북미",
|
||||
"pt": "América Setentrional",
|
||||
"nl": "Noord-Amerika",
|
||||
"fa": "شمال آمریکا",
|
||||
"de": "Nordamerika",
|
||||
"es": "América Norteña",
|
||||
"fr": "Amérique septentrionale",
|
||||
"ja": "北部アメリカ",
|
||||
"it": "America settentrionale",
|
||||
"zh-CN": "北美地區",
|
||||
"ru": "Северная Америка",
|
||||
"uk": "Північна Америка",
|
||||
"pl": "Ameryka Północna"
|
||||
},
|
||||
"wikiDataId": "Q2017699"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "Northern Europe",
|
||||
"region_id": "4",
|
||||
"translations": {
|
||||
"ko": "북유럽",
|
||||
"pt": "Europa Setentrional",
|
||||
"nl": "Noord-Europa",
|
||||
"hr": "Sjeverna Europa",
|
||||
"fa": "شمال اروپا",
|
||||
"de": "Nordeuropa",
|
||||
"es": "Europa del Norte",
|
||||
"fr": "Europe du Nord",
|
||||
"ja": "北ヨーロッパ",
|
||||
"it": "Europa settentrionale",
|
||||
"zh-CN": "北歐",
|
||||
"ru": "Северная Европа",
|
||||
"uk": "Північна Європа",
|
||||
"pl": "Europa Północna"
|
||||
},
|
||||
"wikiDataId": "Q27479"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "Polynesia",
|
||||
"region_id": "5",
|
||||
"translations": {
|
||||
"ko": "폴리네시아",
|
||||
"pt": "Polinésia",
|
||||
"nl": "Polynesië",
|
||||
"hr": "Polinezija",
|
||||
"fa": "پلینزی",
|
||||
"de": "Polynesien",
|
||||
"es": "Polinesia",
|
||||
"fr": "Polynésie",
|
||||
"ja": "ポリネシア",
|
||||
"it": "Polinesia",
|
||||
"zh-CN": "玻里尼西亞",
|
||||
"ru": "Полинезия",
|
||||
"uk": "Полінезія",
|
||||
"pl": "Polinezja"
|
||||
},
|
||||
"wikiDataId": "Q35942"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "South America",
|
||||
"region_id": "2",
|
||||
"translations": {
|
||||
"ko": "남아메리카",
|
||||
"pt": "América do Sul",
|
||||
"nl": "Zuid-Amerika",
|
||||
"hr": "Južna Amerika",
|
||||
"fa": "آمریکای جنوبی",
|
||||
"de": "Südamerika",
|
||||
"es": "América del Sur",
|
||||
"fr": "Amérique du Sud",
|
||||
"ja": "南アメリカ",
|
||||
"it": "America meridionale",
|
||||
"zh-CN": "南美洲",
|
||||
"ru": "Южная Америка",
|
||||
"uk": "Південна Америка",
|
||||
"pl": "Ameryka Południowa"
|
||||
},
|
||||
"wikiDataId": "Q18"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "South-Eastern Asia",
|
||||
"region_id": "3",
|
||||
"translations": {
|
||||
"ko": "동남아시아",
|
||||
"pt": "Sudeste Asiático",
|
||||
"nl": "Zuidoost-Azië",
|
||||
"hr": "Jugoistočna Azija",
|
||||
"fa": "جنوب شرق آسیا",
|
||||
"de": "Südostasien",
|
||||
"es": "Sudeste Asiático",
|
||||
"fr": "Asie du Sud-Est",
|
||||
"ja": "東南アジア",
|
||||
"it": "Sud-est asiatico",
|
||||
"zh-CN": "东南亚",
|
||||
"ru": "Юго-Восточная Азия",
|
||||
"uk": "Південно-Східна Азія",
|
||||
"pl": "Azja Południowo-Wschodnia"
|
||||
},
|
||||
"wikiDataId": "Q11708"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Southern Africa",
|
||||
"region_id": "1",
|
||||
"translations": {
|
||||
"ko": "남아프리카",
|
||||
"pt": "África Austral",
|
||||
"nl": "Zuidelijk Afrika",
|
||||
"hr": "Južna Afrika",
|
||||
"fa": "جنوب آفریقا",
|
||||
"de": "Südafrika",
|
||||
"es": "África austral",
|
||||
"fr": "Afrique australe",
|
||||
"ja": "南部アフリカ",
|
||||
"it": "Africa australe",
|
||||
"zh-CN": "南部非洲",
|
||||
"ru": "Южная Африка",
|
||||
"uk": "Південна Африка",
|
||||
"pl": "Afryka Południowa"
|
||||
},
|
||||
"wikiDataId": "Q27394"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Southern Asia",
|
||||
"region_id": "3",
|
||||
"translations": {
|
||||
"ko": "남아시아",
|
||||
"pt": "Ásia Meridional",
|
||||
"nl": "Zuid-Azië",
|
||||
"hr": "Južna Azija",
|
||||
"fa": "جنوب آسیا",
|
||||
"de": "Südasien",
|
||||
"es": "Asia del Sur",
|
||||
"fr": "Asie du Sud",
|
||||
"ja": "南アジア",
|
||||
"it": "Asia meridionale",
|
||||
"zh-CN": "南亚",
|
||||
"ru": "Южная Азия",
|
||||
"uk": "Південна Азія",
|
||||
"pl": "Azja Południowa"
|
||||
},
|
||||
"wikiDataId": "Q771405"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Southern Europe",
|
||||
"region_id": "4",
|
||||
"translations": {
|
||||
"ko": "남유럽",
|
||||
"pt": "Europa meridional",
|
||||
"nl": "Zuid-Europa",
|
||||
"hr": "Južna Europa",
|
||||
"fa": "جنوب اروپا",
|
||||
"de": "Südeuropa",
|
||||
"es": "Europa del Sur",
|
||||
"fr": "Europe du Sud",
|
||||
"ja": "南ヨーロッパ",
|
||||
"it": "Europa meridionale",
|
||||
"zh-CN": "南欧",
|
||||
"ru": "Южная Европа",
|
||||
"uk": "Південна Європа",
|
||||
"pl": "Europa Południowa"
|
||||
},
|
||||
"wikiDataId": "Q27449"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Western Africa",
|
||||
"region_id": "1",
|
||||
"translations": {
|
||||
"ko": "서아프리카",
|
||||
"pt": "África Ocidental",
|
||||
"nl": "West-Afrika",
|
||||
"hr": "Zapadna Afrika",
|
||||
"fa": "غرب آفریقا",
|
||||
"de": "Westafrika",
|
||||
"es": "África Occidental",
|
||||
"fr": "Afrique de l'Ouest",
|
||||
"ja": "西アフリカ",
|
||||
"it": "Africa occidentale",
|
||||
"zh-CN": "西非",
|
||||
"ru": "Западная Африка",
|
||||
"uk": "Західна Африка",
|
||||
"pl": "Afryka Zachodnia"
|
||||
},
|
||||
"wikiDataId": "Q4412"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "Western Asia",
|
||||
"region_id": "3",
|
||||
"translations": {
|
||||
"ko": "서아시아",
|
||||
"pt": "Sudoeste Asiático",
|
||||
"nl": "Zuidwest-Azië",
|
||||
"hr": "Jugozapadna Azija",
|
||||
"fa": "غرب آسیا",
|
||||
"de": "Vorderasien",
|
||||
"es": "Asia Occidental",
|
||||
"fr": "Asie de l'Ouest",
|
||||
"ja": "西アジア",
|
||||
"it": "Asia occidentale",
|
||||
"zh-CN": "西亚",
|
||||
"ru": "Западная Азия",
|
||||
"uk": "Західна Азія",
|
||||
"pl": "Azja Zachodnia"
|
||||
},
|
||||
"wikiDataId": "Q27293"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "Western Europe",
|
||||
"region_id": "4",
|
||||
"translations": {
|
||||
"ko": "서유럽",
|
||||
"pt": "Europa Ocidental",
|
||||
"nl": "West-Europa",
|
||||
"hr": "Zapadna Europa",
|
||||
"fa": "غرب اروپا",
|
||||
"de": "Westeuropa",
|
||||
"es": "Europa Occidental",
|
||||
"fr": "Europe de l'Ouest",
|
||||
"ja": "西ヨーロッパ",
|
||||
"it": "Europa occidentale",
|
||||
"zh-CN": "西欧",
|
||||
"ru": "Западная Европа",
|
||||
"uk": "Західна Європа",
|
||||
"pl": "Europa Zachodnia"
|
||||
},
|
||||
"wikiDataId": "Q27496"
|
||||
}
|
||||
]
|
6
lib/tasks/study_rake.rake
Normal file
6
lib/tasks/study_rake.rake
Normal file
@ -0,0 +1,6 @@
|
||||
desc "study rake about rails" # desc 是Rake定义的方法,表示对下面定义任务的描述.这个描述会在使用Rake --tasks(或者Rake -T)命令时输出在屏幕上.
|
||||
task :study_rake do # cmd 命令行中执行 rake study_rake 开始执行脚本,task是Rake最重要的方法.它的方法定义是:task(args, &block).任务体是一个block。
|
||||
%w[a b c].each do |d|
|
||||
puts d # 编写你所需的功能代码。
|
||||
end
|
||||
end
|
181
lib/tasks/sync_geo_data.rake
Normal file
181
lib/tasks/sync_geo_data.rake
Normal file
@ -0,0 +1,181 @@
|
||||
# lib/tasks/sync_geo_data.rake
|
||||
require "json"
|
||||
|
||||
namespace :geo do
|
||||
desc "Sync geographical data from JSON"
|
||||
task sync: :environment do
|
||||
# 定义 JSON 文件路径
|
||||
base_path = Rails.root.join("lib", "data")
|
||||
|
||||
# 同步顺序很重要:先同步 Regions -> Subregions -> Countries -> States -> Cities
|
||||
sync_regions(base_path)
|
||||
sync_subregions(base_path)
|
||||
sync_countries(base_path)
|
||||
sync_states(base_path)
|
||||
sync_cities(base_path)
|
||||
end
|
||||
|
||||
def sync_regions(base_path)
|
||||
file_path = base_path.join("regions.json")
|
||||
regions = JSON.parse(File.read(file_path))
|
||||
sum = regions.count
|
||||
count = 1
|
||||
|
||||
regions.each do |data|
|
||||
region = Region.find_or_initialize_by(id: data["id"]) do |r|
|
||||
r.name = data["name"]
|
||||
end
|
||||
puts "Sync Regions[#{count}/#{sum}]: [#{region.name}]"
|
||||
count += 1
|
||||
|
||||
region.update(
|
||||
translations: data["translations"],
|
||||
flag: data["flag"] || true,
|
||||
wiki_data_id: data["wikiDataId"]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def sync_subregions(base_path)
|
||||
file_path = base_path.join("subregions.json")
|
||||
subregions = JSON.parse(File.read(file_path))
|
||||
sum = subregions.count
|
||||
count = 1
|
||||
|
||||
subregions.each do |data|
|
||||
subregion = Subregion.find_or_initialize_by(id: data["id"]) do |s|
|
||||
s.name = data["name"]
|
||||
s.region_id = data["region_id"]
|
||||
end
|
||||
puts "Sync Subregions[#{count}/#{sum}]: [#{subregion.name}]"
|
||||
count += 1
|
||||
|
||||
subregion.update(
|
||||
translations: data["translations"],
|
||||
flag: data["flag"] || true,
|
||||
wiki_data_id: data["wikiDataId"]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def sync_countries(base_path)
|
||||
file_path = base_path.join("countries.json")
|
||||
countries = JSON.parse(File.read(file_path))
|
||||
sum = countries.count
|
||||
count = 1
|
||||
|
||||
countries.each do |data|
|
||||
# puts "Syncing countries for #{data["name"]}"
|
||||
# 处理 Region
|
||||
region = if data["region_id"]
|
||||
Region.find_by(id: data["region_id"])
|
||||
elsif data["region"]
|
||||
Region.find_by(name: data["region"])
|
||||
end
|
||||
|
||||
# 处理 Subregion
|
||||
subregion = nil
|
||||
if data["subregion_id"].present?
|
||||
subregion = Subregion.find_by(id: data["subregion_id"])
|
||||
elsif data["subregion"].present?
|
||||
subregion = Subregion.find_by(name: data["subregion"])
|
||||
end
|
||||
puts "Syncing Country[#{count}/#{sum}] [#{data["name"]}] region: [#{region&.name}] subregion: [#{data["subregion"]}]"
|
||||
count += 1
|
||||
|
||||
# 查找或初始化 Country
|
||||
country = Country.find_or_initialize_by(name: data["name"]) do |c|
|
||||
end
|
||||
|
||||
# 更新 Country 属性
|
||||
country.update(
|
||||
iso3: data["iso3"],
|
||||
numeric_code: data["numeric_code"],
|
||||
iso2: data["iso2"],
|
||||
code: data["iso2"],
|
||||
phonecode: data["phonecode"],
|
||||
capital: data["capital"],
|
||||
currency: data["currency"],
|
||||
currency_name: data["currency_name"],
|
||||
currency_symbol: data["currency_symbol"],
|
||||
tld: data["tld"],
|
||||
native: data["native"],
|
||||
nationality: data["nationality"],
|
||||
timezones: data["timezones"],
|
||||
translations: data["translations"],
|
||||
latitude: data["latitude"],
|
||||
longitude: data["longitude"],
|
||||
emoji: data["emoji"],
|
||||
emoji_u: data["emojiU"],
|
||||
flag: data["flag"] || true,
|
||||
wiki_data_id: data["wikiDataId"]
|
||||
)
|
||||
country.update(region: region) if region != nil
|
||||
country.update(subregion: subregion) if subregion != nil
|
||||
end
|
||||
end
|
||||
|
||||
def sync_states(base_path)
|
||||
file_path = base_path.join("states.json")
|
||||
states = JSON.parse(File.read(file_path))
|
||||
sum = states.count
|
||||
count = 1
|
||||
|
||||
states.each do |data|
|
||||
puts "Syncing State[#{count}/#{sum}] [#{data["name"]}] "
|
||||
count += 1
|
||||
|
||||
state = State.find_or_initialize_by(name: data["name"]) do |s|
|
||||
s.country_id = data["country_id"]
|
||||
end
|
||||
|
||||
state.update(
|
||||
country_code: data["country_code"],
|
||||
fips_code: data["fips_code"],
|
||||
iso2: data["iso2"],
|
||||
code: data["state_code"],
|
||||
state_type: data["type"],
|
||||
level: data["level"],
|
||||
parent_id: data["parent_id"],
|
||||
latitude: data["latitude"],
|
||||
longitude: data["longitude"],
|
||||
flag: data["flag"] || true,
|
||||
wiki_data_id: data["wikiDataId"]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def sync_cities(base_path)
|
||||
file_path = base_path.join("cities.json")
|
||||
cities = JSON.parse(File.read(file_path))
|
||||
sum = cities.count
|
||||
count = 1
|
||||
|
||||
cities.each do |data|
|
||||
city = City.find_or_initialize_by(name: data["name"])
|
||||
|
||||
country = Country.find_by(name: data["country_name"])
|
||||
state = State.find_by(name: data["state_name"])
|
||||
|
||||
puts "Syncing City[#{count}/#{sum}] [#{data["name"]}] Country:[#{country&.name}] "
|
||||
count += 1
|
||||
|
||||
city.update(
|
||||
latitude: data["latitude"],
|
||||
longitude: data["longitude"],
|
||||
flag: data["flag"] || true,
|
||||
wiki_data_id: data["wikiDataId"]
|
||||
)
|
||||
if country != nil
|
||||
city.update(
|
||||
country: country,
|
||||
country_code: country.code,
|
||||
)
|
||||
end
|
||||
city.update(state: state) unless state == nil
|
||||
city.update(state_code: state.code) unless state == nil
|
||||
city.update(active: false) if city.active == nil
|
||||
city.update(priority: 10) if city.priority == nil
|
||||
end
|
||||
end
|
||||
end
|
11
test/fixtures/states.yml
vendored
Normal file
11
test/fixtures/states.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
# This model initially had no columns defined. If you add columns to the
|
||||
# model remove the "{}" from the fixture names and add the columns immediately
|
||||
# below each fixture, per the syntax in the comments below
|
||||
#
|
||||
#one: {}
|
||||
# column: value
|
||||
#
|
||||
#two: {}
|
||||
# column: value
|
11
test/fixtures/subregions.yml
vendored
Normal file
11
test/fixtures/subregions.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
# This model initially had no columns defined. If you add columns to the
|
||||
# model remove the "{}" from the fixture names and add the columns immediately
|
||||
# below each fixture, per the syntax in the comments below
|
||||
#
|
||||
#one: {}
|
||||
# column: value
|
||||
#
|
||||
#two: {}
|
||||
# column: value
|
7
test/models/state_test.rb
Normal file
7
test/models/state_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require "test_helper"
|
||||
|
||||
class StateTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
7
test/models/subregion_test.rb
Normal file
7
test/models/subregion_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require "test_helper"
|
||||
|
||||
class SubregionTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
Loading…
Reference in New Issue
Block a user