china_regions 0.0.1

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.
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