over 3 years ago

系統:

Mac OS X Yosemite 10.10.1
Ruby 2.2.0
Rails 4.2.0

相關連結

source code ( https://github.com/ChouAndy/dynamic_select )
demo ( http://dynamic-select.herokuapp.com/ )
Heroku Toolbelt ( https://toolbelt.heroku.com/ )

前言

練習用 Ruby on Rails 來實作台灣縣市與鄉鎮市區的連動選單。

設定步驟如下

1. 新增專案

$ rails new dynamic_select

2. 新增所需 Models

縣市 ( County )
$ rails g model County name:string --no-timestamps
鄉鎮市區 ( Township )
$ rails g model Township county:belongs_to name:string zip_code:string --no-timestamps

新增好之後,創建資料庫及資料表 ( 目前在 development 環境是使用 SQLite3 )。

$ rake db:create db:migrate

3. 匯入 2013 最新台灣五都縣市及鄉鎮市區資料

可以至以下位置抓取匯入所需的 sql 檔案 ( 依照資料庫種類不同會有不一樣的 sql 語法 )

  • postgresql 專用 sql 檔案 ( 前往 ),存放位置為 db/pg/
  • sqlite3 專用 sql 檔案 ( 前往 ),存放位置為 db/sql/

再來在 seeds.rb 新增匯入 sql 檔的語法。

db/seeds.rb
connection = ActiveRecord::Base.connection

sql_files = ['counties', 'townships']
adapter_type = connection.adapter_name.downcase.to_sym

sql_files.each do |sql_file|
  if adapter_type == :postgresql
    sql = File.read("db/pg/#{sql_file}.sql")
  else
    sql = File.read("db/sql/#{sql_file}.sql")
  end
  statements = sql.split(/;$/)
  statements.pop

  ActiveRecord::Base.transaction do
    statements.each do |statement|
      connection.execute(statement)
    end
  end
end

執行匯入指令

$ rake db:seed

4. 以訂單 ( Order ) 為範例

CRUD

使用鷹架產生 Order 的 CRUD

$ rails g scaffold order county:belongs_to township:belongs_to total:integer
$ rake db:migrate
設定首頁
config/routes.rb
Rails.application.routes.draw do
  ...
  root 'orders#index'
end
Model 設定
app/models/county.rb
class County < ActiveRecord::Base
  has_many :orders
  has_many :township
end
app/models/township.rb
class County < ActiveRecord::Base
  belongs_to :county
  has_many :orders
end
View 設定

修改部分的 orders views

app/views/orders/_form.html.erb
  ...
  <div class="field">
    <%= f.label :county_id %><br />
    <%= f.collection_select :county_id, County.order(:name), :id, :name, include_blank: true %>
  </div>
  <div class="field">
    <%= f.label :state_id, "Township" %><br />
    <%= f.grouped_collection_select :township_id, County.order(:name), :township, :name, :id, :name, include_blank: true %>
  </div>
  ...
app/views/orders/index.html.erb
  ...
  <tr>
    <td><%= order.county.try(:name) %></td>
    <td><%= order.township.try(:name) %></td>
    <td><%= order.township.try(:zip_code) %></td>
    <td><%= order.total %></td>
    ...
  </tr>
  ...
app/views/orders/show.html.erb
...
<p>
  <strong>County:</strong>
  <%= @order.county.try(:name)%>
</p>

<p>
  <strong>Township:</strong>
  <%= @order.township.try(:name) %>
</p>

<p>
  <strong>Zipcode:</strong>
  <%= @order.township.try(:zip_code) %>
</p>
...
javescripts 設定

新增 連動選單用的 jQuery 語法

app/assets/javascripts/order.coffee
$ ->
  filter_township = ->
    county = $('#order_county_id :selected').text()
    escaped_county = county.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1')
    options = $(township).filter("optgroup[label='#{escaped_county}']").html()
    if options
      $('#order_township_id').html(options)
      $('#order_township_id').parent().show()
    else
      $('#order_township_id').empty()
      $('#order_township_id').html('<option value=""></option>')
      $('#order_township_id').parent().hide()

  $('#order_township_id').parent().hide()
  township = $('#order_township_id').html()

  if $('#order_county_id').val() != ''
    filter_township()
  $('#order_county_id').change ->
    filter_township()

移除 turbolinks,因為會導致連動選單用的 jQuery 語法無作用。

app/assets/javascripts/application.js
//= require turbolinks

5. 部署至 Heroku 伺服器

安裝 Heroku Toolbelt

下載網址:https://toolbelt.heroku.com/
Mac OS X 可以選擇使用 brew 安裝

$ brew install heroku-toolbelt
Gemfile 設定
...
ruby '2.2.0'

# For heroku
group :production do
  gem 'pg'
  gem 'rails_12factor'
end
...
group :development, :test do
  gem 'sqlite3'
end
...
config 設定
config/environments/production.rb
  ...
  config.assets.compile = true
  ...
database 設定

因為在 Heroku 伺服器不能使用 SQLite,但是有提供 Postgresql,所以,我們要修改一下 database 的設定。

config/database.yml
production:
  adapter: postgresql
  encoding: unicode
  pool: 5
開始部署

第一次應該會要你輸入 Heroku 的帳號密碼來認證

$ heroku create
$ git push heroku master
$ heroku run rake db:migrate db:seed
$ heroku open

如果沒有出現錯誤訊息就大功告成哩!!

← 使用 paperclip 實作任意格式檔案上傳 打造專屬 gem - part 1 - 新增、打包、發布 →
 
comments powered by Disqus