china_regions 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lean.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Copyright (c) 2013 Encore
2
+
3
+ MIT License
4
+
5
+ ChinaRegions is released under the MIT license.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # ChinaRegions
2
+
3
+ 中国省份,城市,地区[地级市]. 紧支持 Ruby on Rails 程序.
4
+
5
+
6
+ ## How to use it
7
+
8
+ 添加一下代码到你的 Gemfile:
9
+
10
+ gem 'china_regions', :git => 'git://github.com/encoreshao/china_regions.git'
11
+
12
+ bundle install
13
+
14
+ 执行:
15
+
16
+ rails g china_regions:install
17
+
18
+ 随后你可以看到控制台:
19
+ * 复制 数据源cities 到 config 目录. config/cities.yml
20
+ * 创建 migration 文件到db/migrate 目录 db/migrate/create_china_regions_tables.rb
21
+ * 执行 `rake db:migrate` 添加三张表(provinces, cities, districts).
22
+ * 执行 `rake china_regions:import` 导入数据.
23
+
24
+
25
+ 此时 你可能需要添加三个model[`Province`, `City`, `District`]到你应用中:
26
+
27
+ 你可以执行 `rails g` 查看到 generator LIST.
28
+
29
+ 执行 rails g china_regions:regions models
30
+
31
+ 查看 app/models:
32
+
33
+ create app/models/province.rb
34
+ create app/models/city.rb
35
+ create app/models/district.rb
36
+
37
+
38
+ ## Contributing
39
+
40
+ Thank you for XuHao
41
+
42
+
43
+ ## License
44
+
45
+ ChinaRegions is released under the MIT license.
46
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
@@ -0,0 +1,30 @@
1
+ module ChinaRegions
2
+ class FetchOptionsController < ::ActionController::Metal
3
+
4
+ def index
5
+ if params_valid?(params) and parent_klass = params[:parent_klass].classify.safe_constantize.find(params[:parent_id])
6
+ table_name = params[:klass].tableize
7
+ regions = parent_klass.__send__(table_name).select("#{table_name}.id, #{table_name}.name")
8
+ if has_level_column?(params[:klass])
9
+ regions = regions.order('level ASC')
10
+ else
11
+ regions = regions.order('name ASC')
12
+ end
13
+ self.response_body = regions.to_json
14
+ else
15
+ self.response_body = [].to_json
16
+ end
17
+ end
18
+
19
+
20
+ protected
21
+ def has_level_column?(klass_name)
22
+ klass_name.classify.safe_constantize.try(:column_names).to_a.include?('level')
23
+ end
24
+
25
+ def params_valid?(params)
26
+ params[:klass].present? and params[:parent_klass] =~ /^province|city$/i and params[:parent_id].present?
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ class City < ActiveRecord::Base
4
+
5
+ attr_accessible :name, :province_id, :level, :zip_code, :name_en, :name_abbr
6
+
7
+ belongs_to :province
8
+ has_many :districts, dependent: :destroy
9
+
10
+ scope :with_province, ->(province) { where(province_id: province) }
11
+
12
+ def short_name
13
+ @short_name ||= name.gsub(/市|自治州|地区|特别行政区/, '')
14
+ end
15
+
16
+ def siblings
17
+ @siblings ||= scoped.with_province(self.province_id)
18
+ end
19
+
20
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ class District < ActiveRecord::Base
4
+
5
+ attr_accessible :name, :city_id, :name_en, :name_abbr
6
+
7
+ belongs_to :city
8
+ belongs_to :province
9
+
10
+ scope :with_city, ->(city) { where(city_id: city) }
11
+
12
+ def short_name
13
+ @short_name ||= name.gsub(/区|县|市|自治县/, '')
14
+ end
15
+
16
+ def siblings
17
+ @siblings ||= scoped.with_city(self.city_id)
18
+ end
19
+
20
+ end
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../lib/china_regions/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Encore Shao"]
6
+ gem.email = ["encore.shao@gmail.com"]
7
+ gem.description = %q{China regions Ruby on rails interface}
8
+ gem.summary = %q{China regions Ruby on rails interface}
9
+ gem.homepage = "http://github.com/encoreshao"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "china_regions"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = ChinaRegions::VERSION
17
+
18
+ gem.add_dependency 'jquery-rails'
19
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ match '/china_regions/fetch_options', to: ChinaRegions::FetchOptionsController.action(:index)
3
+ end
@@ -0,0 +1,5 @@
1
+ require "rails"
2
+
3
+ module ChinaRegions
4
+ class Engine < Rails::Engine;end
5
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+
3
+ module ChinaRegions
4
+ module Helper
5
+
6
+ module FormHelper
7
+ def region_select(object, methods, options = {}, html_options = {})
8
+ output = ''
9
+
10
+ html_options[:class] ?
11
+ (html_options[:class].prepend('region_select ')) :
12
+ (html_options[:class] = 'region_select')
13
+
14
+ if Array === methods
15
+ methods.each_with_index do |method, index|
16
+ if klass = method.to_s.classify.safe_constantize
17
+ choices = index == 0 ? klass.all.collect {|p| [ p.name, p.id ] } : []
18
+ next_method = methods.at(index + 1)
19
+
20
+ set_options(method, options, klass)
21
+ set_html_options(object, method, html_options, next_method)
22
+
23
+ output << select(object, "#{method.to_s}_id", choices, options = options, html_options = html_options)
24
+ else
25
+ raise "Method '#{method}' is not a vaild attribute of #{object}"
26
+ end
27
+ end
28
+ else
29
+ if klass = methods.to_s.classify.safe_constantize
30
+ options[:prompt] = region_prompt(klass)
31
+ output << select(object, methods, klass.all.collect {|p| [ p.name, p.id ] }, options = options, html_options = html_options)
32
+ else
33
+ raise "Method '#{method}' is not a vaild attribute of #{object}"
34
+ end
35
+ end
36
+
37
+ output << javascript_tag(js_output)
38
+ output.html_safe
39
+ end
40
+
41
+
42
+ private
43
+
44
+ def set_options(method, options, region_klass)
45
+ if respond_to?("#{method}_select_prompt")
46
+ options[:prompt] = __send__("#{method}_select_prompt")
47
+ else
48
+ options[:prompt] = region_prompt(region_klass)
49
+ end
50
+ end
51
+
52
+ def set_html_options(object, method, html_options, next_region)
53
+ html_options[:data] ? (html_options[:data][:region_klass] = "#{method.to_s}") : (html_options[:data] = { region_klass: "#{method.to_s}" })
54
+ if next_region
55
+ html_options[:data].merge!(region_target: "#{object}_#{next_region.to_s}_id", region_target_kalss: next_region.to_s)
56
+ else
57
+ html_options[:data].delete(:region_target)
58
+ html_options[:data].delete(:region_target_kalss)
59
+ end
60
+ end
61
+
62
+ def region_prompt(region_klass)
63
+ human_name = region_klass.model_name.human
64
+ "请选择#{human_name}"
65
+ end
66
+
67
+ def js_output
68
+ %~
69
+ $(function(){
70
+ $('body').on('change', '.region_select', function(event) {
71
+ var self, targetDom;
72
+ self = $(event.currentTarget);
73
+ targetDom = $('#' + self.data('region-target'));
74
+ if (targetDom.size() > 0) {
75
+ $.getJSON('/china_regions/fetch_options', {klass: self.data('region-target-kalss'), parent_klass: self.data('region-klass'), parent_id: self.val()}, function(data) {
76
+ $('option[value!=""]', targetDom).remove();
77
+ $.each(data, function(index, value) {
78
+ targetDom.append("<option value='" + value.id + "'>" + value.name + "</option>");
79
+ });
80
+ })
81
+ }
82
+ });
83
+ });
84
+ ~
85
+ end
86
+
87
+ end
88
+
89
+
90
+ module FormBuilder
91
+ def region_select(methods, options = {}, html_options = {})
92
+ @template.region_select(@object_name, methods, options = options, html_options = html_options)
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+
99
+
100
+ ActionView::Base.send :include, ChinaRegions::Helper::FormHelper
101
+ ActionView::Helpers::FormBuilder.send :include, ChinaRegions::Helper::FormBuilder
@@ -0,0 +1,3 @@
1
+ module ChinaRegions
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "china_regions/version"
2
+ require 'china_regions/engine' if defined? Rails
3
+
4
+ module ChinaRegions;end
5
+
6
+ require 'china_regions/helper'
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ module ChinaRegions
4
+ class InstallGenerator < Rails::Generators::Base
5
+ include Rails::Generators::Migration
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def capy_migration_file
9
+ migration_template "migration.rb", "db/migrate/create_china_regions_tables.rb"
10
+ end
11
+
12
+ def capy_cities_file
13
+ copy_file 'cities.yml', 'config/cities.yml'
14
+ end
15
+
16
+ def execute_migrate
17
+ rake("db:migrate")
18
+ end
19
+
20
+ def import_cities_to_database
21
+ rake('china_regions:import')
22
+ end
23
+
24
+ def self.next_migration_number(dirname)
25
+ if ActiveRecord::Base.timestamped_migrations
26
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
27
+ else
28
+ "%.3d" % (current_migration_number(dirname) + 1)
29
+ end
30
+ end
31
+ end
32
+ end