Rails 为州选择下拉菜单? ?

我想知道是否有一些已经内置的轨道功能,以便它会创建一个选择下拉列表与所有美国各州,所以我不必手动输入它。我在网上搜索了一下,但是一无所获。有什么建议可以让我不必手动输入所有的状态吗?

41052 次浏览

一些帮助文件

def us_states
[
['Alabama', 'AL'],
['Alaska', 'AK'],
['Arizona', 'AZ'],
['Arkansas', 'AR'],
['California', 'CA'],
['Colorado', 'CO'],
['Connecticut', 'CT'],
['Delaware', 'DE'],
['District of Columbia', 'DC'],
['Florida', 'FL'],
['Georgia', 'GA'],
['Hawaii', 'HI'],
['Idaho', 'ID'],
['Illinois', 'IL'],
['Indiana', 'IN'],
['Iowa', 'IA'],
['Kansas', 'KS'],
['Kentucky', 'KY'],
['Louisiana', 'LA'],
['Maine', 'ME'],
['Maryland', 'MD'],
['Massachusetts', 'MA'],
['Michigan', 'MI'],
['Minnesota', 'MN'],
['Mississippi', 'MS'],
['Missouri', 'MO'],
['Montana', 'MT'],
['Nebraska', 'NE'],
['Nevada', 'NV'],
['New Hampshire', 'NH'],
['New Jersey', 'NJ'],
['New Mexico', 'NM'],
['New York', 'NY'],
['North Carolina', 'NC'],
['North Dakota', 'ND'],
['Ohio', 'OH'],
['Oklahoma', 'OK'],
['Oregon', 'OR'],
['Pennsylvania', 'PA'],
['Puerto Rico', 'PR'],
['Rhode Island', 'RI'],
['South Carolina', 'SC'],
['South Dakota', 'SD'],
['Tennessee', 'TN'],
['Texas', 'TX'],
['Utah', 'UT'],
['Vermont', 'VT'],
['Virginia', 'VA'],
['Washington', 'WA'],
['West Virginia', 'WV'],
['Wisconsin', 'WI'],
['Wyoming', 'WY']
]
end

以某种形式

<%= select_tag :state, options_for_select(us_states) %>

我不知道是否有一些内置的 Rails,使 HTML 选择字段填充美国各州。

但这里有一段视频解释了这一点: Http://railscasts.com/episodes/88-dynamic-select-menus

我希望它能派上用场。

谢谢 Codeglot。如果有人想要显示两个字母的州缩写而不是全名:

def us_states
[
['AK', 'AK'],
['AL', 'AL'],
['AR', 'AR'],
['AZ', 'AZ'],
['CA', 'CA'],
['CO', 'CO'],
['CT', 'CT'],
['DC', 'DC'],
['DE', 'DE'],
['FL', 'FL'],
['GA', 'GA'],
['HI', 'HI'],
['IA', 'IA'],
['ID', 'ID'],
['IL', 'IL'],
['IN', 'IN'],
['KS', 'KS'],
['KY', 'KY'],
['LA', 'LA'],
['MA', 'MA'],
['MD', 'MD'],
['ME', 'ME'],
['MI', 'MI'],
['MN', 'MN'],
['MO', 'MO'],
['MS', 'MS'],
['MT', 'MT'],
['NC', 'NC'],
['ND', 'ND'],
['NE', 'NE'],
['NH', 'NH'],
['NJ', 'NJ'],
['NM', 'NM'],
['NV', 'NV'],
['NY', 'NY'],
['OH', 'OH'],
['OK', 'OK'],
['OR', 'OR'],
['PA', 'PA'],
['RI', 'RI'],
['SC', 'SC'],
['SD', 'SD'],
['TN', 'TN'],
['TX', 'TX'],
['UT', 'UT'],
['VA', 'VA'],
['VT', 'VT'],
['WA', 'WA'],
['WI', 'WI'],
['WV', 'WV'],
['WY', 'WY']
]
end

为此,我通常使用卡门和卡门铁路宝石。

Https://github.com/jim/carmen

Https://github.com/jim/carmen-rails

因为我的项目仍然是 Ruby 1.8,我必须使用 Ruby-18分支,所以我在 Gemfile 中有以下内容:

gem 'carmen', :git => 'git://github.com/jim/carmen.git', :tag => 'ruby-18'
gem 'carmen-rails', :git => 'git://github.com/jim/carmen-rails.git'

然后,以编辑: address 模型对象的: state _ code 字段的形式为所有 US 州创建 select 标记..。

subregion_select(:address, :state_code, Carmen::Country.coded('US'))

万一这个不管用:

<%= select_tag :state, us_states%>

试试这个:

 <%=select_tag 'State', options_for_select(us_states),:name=>"state",:id=>"state"%>

您有一个 gem 可以帮助您: 国家宝石Country _ select集成,因此您有一个完整的状态输入解决方案。

另外,如果你想减少 gem 依赖列表,你可以这样做:

 <%= f.select :country_code, ::ISO3166::Country.all_names_with_codes,{ include_blank: true } %>

这是一个更详细的演练,我使用的是 Rails 4:

在 helpers 文件夹下,我创建了 state _ helper. rb

Inside state _ helper. rb:

module StatesHelper


def us_states
[
['Alabama', 'AL'],
['Alaska', 'AK'],
['Arizona', 'AZ'],
['Arkansas', 'AR'],
['California', 'CA'],
['Colorado', 'CO'],
['Connecticut', 'CT'],
['Delaware', 'DE'],
['District of Columbia', 'DC'],
['Florida', 'FL'],
['Georgia', 'GA'],
['Hawaii', 'HI'],
['Idaho', 'ID'],
['Illinois', 'IL'],
['Indiana', 'IN'],
['Iowa', 'IA'],
['Kansas', 'KS'],
['Kentucky', 'KY'],
['Louisiana', 'LA'],
['Maine', 'ME'],
['Maryland', 'MD'],
['Massachusetts', 'MA'],
['Michigan', 'MI'],
['Minnesota', 'MN'],
['Mississippi', 'MS'],
['Missouri', 'MO'],
['Montana', 'MT'],
['Nebraska', 'NE'],
['Nevada', 'NV'],
['New Hampshire', 'NH'],
['New Jersey', 'NJ'],
['New Mexico', 'NM'],
['New York', 'NY'],
['North Carolina', 'NC'],
['North Dakota', 'ND'],
['Ohio', 'OH'],
['Oklahoma', 'OK'],
['Oregon', 'OR'],
['Pennsylvania', 'PA'],
['Puerto Rico', 'PR'],
['Rhode Island', 'RI'],
['South Carolina', 'SC'],
['South Dakota', 'SD'],
['Tennessee', 'TN'],
['Texas', 'TX'],
['Utah', 'UT'],
['Vermont', 'VT'],
['Virginia', 'VA'],
['Washington', 'WA'],
['West Virginia', 'WV'],
['Wisconsin', 'WI'],
['Wyoming', 'WY']
]
end
end

在 config-> 环境下,我将以下内容放在 development.rb 和 production.rb 中

config.action_controller.include_all_helpers = true

最后,在我的视图中我放入(这是用 Slim HTML 打印出来的)

= form_for :order_submissions, url: order_url, html: { id: "order_form"} do |f|
fieldset
.form-group
= f.select(:state, options_for_select(us_states, "CA"))

“ CA”在加载时的下拉菜单中预先选择 California。

注意: 我没有使用 select_tag。使用它给了我一个未定义的 select_tag方法错误(select _ tag 在 Ruby 指南中,怎么可能是未定义的?)仅仅使用 select就可以了。

我已经创建了一个示例项目,其中详细说明了如何在 Rails 4.2.2和 Ruby 2.2.2 https://rubyplus.com/articles/2501中创建下拉菜单

我发现了使用助手来包含状态的问题。它在创建新记录时工作得很完美,但是如果我想编辑现有记录,我希望在下拉框中预先选择数据库中的状态。我不能用这个帮手让它工作。但是如果您创建一个简单的 state 表,它就可以工作。以下是对我有效的方法:

为选择框选项创建状态表

生成一个 State 模型文件和数据库表,其中只有 State _ code 和 State _ name (或者任何您想称呼它们的列)。 rails g model State state_code:string:uniq state_name:string --no-timestamps --no-test-framework.这将在 db/shift 文件夹中生成一个迁移文件。如果不需要 id 列,可以通过在 create _ table 块声明中插入 , id: false来编辑它。

# db/migrate/timestamp_create_states.rb
class CreateStates < ActiveRecord::Migration
def change
create_table :states, id: false do |t|
t.string :state_code, null: false
t.string :state_name
end
add_index :states, :state_code, unique: true
end
end

并迁移数据库 rake db:migrate

可以使用种子文件填充表。确保删除或注释掉种子文件中以前加载的任何数据,这样就不会添加重复的数据。

#db/seeds.rb
states = State.create!([
{ state_name: 'Alaska', state_code: 'AK' },
{ state_name: 'Alabama', state_code: 'AL' },
{ state_name: 'Arkansas', state_code: 'AR' },
{ state_name: 'Arizona', state_code: 'AZ' },
{ state_name: 'California', state_code: 'CA' },
{ state_name: 'Colorado', state_code: 'CO' },
{ state_name: 'Connecticut', state_code: 'CT' },
{ state_name: 'District of Columbia', state_code: 'DC' },
{ state_name: 'Delaware', state_code: 'DE' },
{ state_name: 'Florida', state_code: 'FL' },
{ state_name: 'Georgia', state_code: 'GA' },
{ state_name: 'Hawaii', state_code: 'HI' },
{ state_name: 'Iowa', state_code: 'IA' },
{ state_name: 'Idaho', state_code: 'ID' },
{ state_name: 'Illinois', state_code: 'IL' },
{ state_name: 'Indiana', state_code: 'IN' },
{ state_name: 'Kansas', state_code: 'KS' },
{ state_name: 'Kentucky', state_code: 'KY' },
{ state_name: 'Louisiana', state_code: 'LA' },
{ state_name: 'Massachusetts', state_code: 'MA' },
{ state_name: 'Maryland', state_code: 'MD' },
{ state_name: 'Maine', state_code: 'ME' },
{ state_name: 'Michigan', state_code: 'MI' },
{ state_name: 'Minnesota', state_code: 'MN' },
{ state_name: 'Missouri', state_code: 'MO' },
{ state_name: 'Mississippi', state_code: 'MS' },
{ state_name: 'Montana', state_code: 'MT' },
{ state_name: 'North Carolina', state_code: 'NC' },
{ state_name: 'North Dakota', state_code: 'ND' },
{ state_name: 'Nebraska', state_code: 'NE' },
{ state_name: 'New Hampshire', state_code: 'NH' },
{ state_name: 'New Jersey', state_code: 'NJ' },
{ state_name: 'New Mexico', state_code: 'NM' },
{ state_name: 'Nevada', state_code: 'NV' },
{ state_name: 'New York', state_code: 'NY' },
{ state_name: 'Ohio', state_code: 'OH' },
{ state_name: 'Oklahoma', state_code: 'OK' },
{ state_name: 'Oregon', state_code: 'OR' },
{ state_name: 'Pennsylvania', state_code: 'PA' },
{ state_name: 'Puerto Rico', state_code: 'PR' },
{ state_name: 'Rhode Island', state_code: 'RI' },
{ state_name: 'South Carolina', state_code: 'SC' },
{ state_name: 'South Dakota', state_code: 'SD' },
{ state_name: 'Tennessee', state_code: 'TN' },
{ state_name: 'Texas', state_code: 'TX' },
{ state_name: 'Utah', state_code: 'UT' },
{ state_name: 'Virginia', state_code: 'VA' },
{ state_name: 'Vermont', state_code: 'VT' },
{ state_name: 'Washington', state_code: 'WA' },
{ state_name: 'Wisconsin', state_code: 'WI' },
{ state_name: 'West Virginia', state_code: 'WV' },
{ state_name: 'Wyoming', state_code: 'WY' }
])

然后运行 rake 任务为 dbrake db:seed播种

在表单中,你可以添加这个作为你的选择框(我使用 state _ code 作为字段名,但是你也可以只添加 state 或者任何你想要的名字) :

<%= f.label :state_code, 'State', class: 'control-label' %>
<%= f.collection_select(:state_code, State.select(:state_name, :state_code),
:state_code, :state_name, {selected: 'CA'}, {class: 'form-control'}) %>

Rails 表单块中的 Collection _ select helper 方法格式为 f.collection_select(method, collection, value_method, text_method, options = {}, html_options = {})。如果希望 state _ code 同时作为下拉框的文本和值,那么在第一个 select 参数和 text _ method 中将: state _ name 更改为: state _ code (注意,文本和值顺序颠倒了)。在选项中,我预先选择了“ CA”,但是只对一个新表单这样做,而不编辑(或者每次都用 CA 覆盖该值)。您可以将其更改为空白 {include_blank: true},或者添加提示 {prompt: 'Select State'},或者只是将其默认设置为选定的值或第一个值,并使用空散列 {}。如果您想使该字段成为必需的,您可以将其添加到 html 选项 {class: 'form-control', required: true}

现在在表单中,您可以从 state 表中填充它,它将在编辑记录时预选该值。

看看这个 https://rubygems.org/gems/country_state_select

Country State Select 是一个图书馆,它提供了一个简单的 API 来生成国家、州/省和城市的下拉列表,以便在表单中使用。

如果实现正确,州/省下拉列表将根据用户选择的国家填充适当的区域。

例如,如果用户选择“美利坚合众国”作为国家下拉列表,国家下拉列表将填充50个合适的州加上哥伦比亚特区,然后用户可以根据州选择列出城市,但目前城市是有限的。

为了让这个和 simple_form一起工作,我做了这个。

在我的 user.rb模型中添加了以下内容:

STATES =
[
['Alabama', 'AL'],
['Alaska', 'AK'],
['Arizona', 'AZ'],
['Arkansas', 'AR'],
['California', 'CA'],
['Colorado', 'CO'],
['Connecticut', 'CT'],
['Delaware', 'DE'],
['District of Columbia', 'DC'],
['Florida', 'FL'],
['Georgia', 'GA'],
['Hawaii', 'HI'],
['Idaho', 'ID'],
['Illinois', 'IL'],
['Indiana', 'IN'],
['Iowa', 'IA'],
['Kansas', 'KS'],
['Kentucky', 'KY'],
['Louisiana', 'LA'],
['Maine', 'ME'],
['Maryland', 'MD'],
['Massachusetts', 'MA'],
['Michigan', 'MI'],
['Minnesota', 'MN'],
['Mississippi', 'MS'],
['Missouri', 'MO'],
['Montana', 'MT'],
['Nebraska', 'NE'],
['Nevada', 'NV'],
['New Hampshire', 'NH'],
['New Jersey', 'NJ'],
['New Mexico', 'NM'],
['New York', 'NY'],
['North Carolina', 'NC'],
['North Dakota', 'ND'],
['Ohio', 'OH'],
['Oklahoma', 'OK'],
['Oregon', 'OR'],
['Pennsylvania', 'PA'],
['Puerto Rico', 'PR'],
['Rhode Island', 'RI'],
['South Carolina', 'SC'],
['South Dakota', 'SD'],
['Tennessee', 'TN'],
['Texas', 'TX'],
['Utah', 'UT'],
['Vermont', 'VT'],
['Virginia', 'VA'],
['Washington', 'WA'],
['West Virginia', 'WV'],
['Wisconsin', 'WI'],
['Wyoming', 'WY']
]

在我看来使用 simple _ form:

<%= simple_form_for(@user) do |f| %>
<%= f.input :state, as: :select, collection: User::STATES %>
<%= f.button :submit %>
<% end %>

如果要在全名上保存状态

# frozen_string_literal: true


module StateHelper


def us_states
[
['Alabama'],
['Alaska'],
['Arizona'],
['Arkansas'],
['California'],
['Colorado'],
['Connecticut'],
['Delaware'],
['District of Columbia'],
['Florida'],
['Georgia'],
['Hawaii'],
['Idaho'],
['Illinois'],
['Indiana'],
['Iowa'],
['Kansas'],
['Kentucky'],
['Louisiana'],
['Maine'],
['Maryland'],
['Massachusetts'],
['Michigan'],
['Minnesota'],
['Mississippi'],
['Missouri'],
['Montana'],
['Nebraska'],
['Nevada'],
['New Hampshire'],
['New Jersey'],
['New Mexico'],
['New York'],
['North Carolina'],
['North Dakota'],
['Ohio'],
['Oklahoma'],
['Oregon'],
['Pennsylvania'],
['Puerto Rico'],
['Rhode Island'],
['South Carolina'],
['South Dakota'],
['Tennessee'],
['Texas'],
['Utah'],
['Vermont'],
['Virginia'],
['Washington'],
['West Virginia'],
['Wisconsin'],
['Wyoming']
]
end
end


然后形成

<%= f.select :state, options_for_select(us_states), class:"form-control", required: true %>


用大麻。我把我的代码放在 Config/initializer/us _ state. rb中,但它可以在助手中工作,或者放在你喜欢的任何地方:

US_STATES = {
'AL': 'Alabama',
'AK': 'Alaska',
'AZ': 'Arizona',
'AR': 'Arkansas',
'CA': 'California',
'CO': 'Colorado',
'CT': 'Connecticut',
'DE': 'Delaware',
'DC': 'District of Columbia',
'FL': 'Florida',
'GA': 'Georgia',
'HI': 'Hawaii',
'ID': 'Idaho',
'IL': 'Illinois',
'IN': 'Indiana',
'IA': 'Iowa',
'KS': 'Kansas',
'KY': 'Kentucky',
'LA': 'Louisiana',
'ME': 'Maine',
'MD': 'Maryland',
'MA': 'Massachusetts',
'MI': 'Michigan',
'MN': 'Minnesota',
'MS': 'Mississippi',
'MO': 'Missouri',
'MT': 'Montana',
'NE': 'Nebraska',
'NV': 'Nevada',
'NH': 'New Hampshire',
'NJ': 'New Jersey',
'NM': 'New Mexico',
'NY': 'New York',
'NC': 'North Carolina',
'ND': 'North Dakota',
'OH': 'Ohio',
'OK': 'Oklahoma',
'OR': 'Oregon',
'PA': 'Pennsylvania',
'PR': 'Puerto Rico',
'RI': 'Rhode Island',
'SC': 'South Carolina',
'SD': 'South Dakota',
'TN': 'Tennessee',
'TX': 'Texas',
'UT': 'Utah',
'VT': 'Vermont',
'VA': 'Virginia',
'WA': 'Washington',
'WV': 'West Virginia',
'WI': 'Wisconsin',
'WY': 'Wyoming'
}

然后,以我的形式:

<%= form.select :state, US_STATES.invert.sort %>

因为存储的是两个字母的代码,所以如果我想显示状态的名称,我只需要在散列中引用两个字母的键:

<%= US_STATES[state] %>

如果你想变得非常灵活,在一个语言环境文件中初始化它们(例如,Config/locales/en.yml) :

---
en:
us_states:
AL: Alabama
AK: Alaska
AZ: Arizona
# etc.

并通过以下方式在视图中访问它们:

<%= t "us_states.#{state}" %>

当你在你的应用程序中支持多种语言时,这实际上对国家和语言代码更有效。