Rails为国家选择下拉菜单?


74

我想知道是否可能已经有一些用于Rails的内置函数,以便它将在美国所有州创建一个选择下拉列表,这样我就不必手动输入它了。我在网上搜索,但找不到任何内容。关于如何执行操作的任何建议,我不必手动输入所有状态?

Answers:


144

一些帮助文件

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) %>

NP。这种东西不会包含在rails中。它不是不可知论的,并且包括所有国家,州等……根本不是一团糟。
thenengah 2011年

我有一个小问题。在我的档案中显示的状态arent。有什么建议?我只是得到一个空的选择下拉框。也许我应该把它做一部分?
杰克

20
<%= select_tag :state, options_for_select(us_states) %>
thenengah 2011年

4
如果在form_for中:= f.select :state, options_for_select(us_states),{}, class: 'form-control'
Robbie Guilfoyle 2014年

这对我有用。关于如何在“显示”视图中撤消此操作的任何建议?他们可以在表格中选择“ Arizona”,并将其记录为“ AZ”在数据库中;但是,在显示页面上,它显示为“ AZ”,而不是“亚利桑那”。
Christopher Warrington

30

感谢Codeglot。如果有人想显示2字母状态的缩写而不是全名:

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

19

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

在helpers文件夹下,我创建了states_helper.rb

在states_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

在配置->环境下,我将以下内容放入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”会在加载时的下拉菜单中预先选择“加利福尼亚”。

注意:我没有使用select_tag。使用它给我带来了一个未定义的方法错误select_tag(对于Ruby指南中的select_tag,如何定义它是不确定的?),使用select它就可以了。


18

为此,我通常使用Carmen和Carmen-Rails宝石。

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字段的形式为所有美国州创建select标签。

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

6

我发现使用帮助器包含状态存在问题。在创建新记录时,它可以完美工作,但是如果我要编辑现有记录,则希望在下拉框中预先选择数据库中的状态。我不能使用助手来工作。但是,如果您创建一个简单的状态表,它确实可以工作。这对我有用:

为选择框选项创建状态表

生成仅包含state_code和state_name(或您要调用的名称)列的State模型文件和数据库表。 rails g model State state_code:string:uniq state_name:string --no-timestamps --no-test-framework。这将在db / migrate文件夹中生成一个迁移文件。如果您不想使用id列,则可以通过将其插入, id: false到create_table块声明中来对其进行编辑。

# 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任务为数据库播种 rake db:seed

在您的表单中,您可以将其添加为选择框(我使用state_code作为字段名,但您可以使其仅显示状态或您想要的任何名称):

<%= 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}

现在,您可以在表单中从状态表中填充它,并且它将在编辑记录时预先选择值。


我觉得这个答案最好。我不喜欢将数据硬编码到代码中的想法。
Jason Swett

1
我认为这太过分了-各州不太可能改变(尽管最近发生了政治事件),所以硬编码就可以了。
elsurudo

同意,硬编码可能没问题,但史蒂夫(Steve)指出,他试图通过下拉菜单来预先选择状态。我正在用Rails 5编码,这就是我所做的。我在下拉框之前设置了一条if语句,以检查状态是否已记录或为零。如果为零,则将temp变量设置为所选的默认状态。如果已记录,则将temp变量设置为该状态。然后,我在select中调用了temp变量,如下所示:<%= f.select :state, options_for_select(us_states, @temp_state), id: :profile_state %>现在,弄清楚如何显示状态的全名。
Christopher Warrington

这是我用来设置temp变量的代码: <% if profile.state.nil? @temp_state = 'Arizona' else @temp_state = profile.state end %> 抱歉,缩进和换行符未显示在这些注释中。
Christopher Warrington

6

为了使它与 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 %>

4

万一这不起作用:

<%= select_tag :state, us_states%>

尝试这个 :

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

我正在使用Rails 3,这是我必须做的才能使此方法起作用。神奇的回答萨钦。
肖恩·德普雷

3

您有一个可以帮助您的gem:与country_select集成的country宝石,因此您为州输入提供了完整的解决方案。

另外,如果要减少gem依赖项列表,可以执行以下操作:

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

1

检查此https://rubygems.org/gems/country_state_select

Country State Select是一个提供易于使用的API的库,可以生成用于表格的Country,州/省和城市下拉列表。

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

例如,如果用户为“国家/地区”下拉列表选择“美国”,则“州”下拉列表将填充50个适当的州以及哥伦比亚特区,然后用户可以根据州选择列出城市,但当前城市有限。


0

我不知道是否有内置的Rails可以使HTML选择字段充满美国各州。

但是这里有一个截屏视频,解释了这一点: http //railscasts.com/episodes/88-dynamic-select-menus

我希望它会有用。


较早版本的Rails带有带有州和国家/地区列表的select标签助手,但是正如Codeglot指出的那样,它并不适当地不可知,因此已被删除。就像复制他的代码一样容易:-)。另请注意,链接的railscast已更新。
汤姆·哈里森


0

如果要以全名保存状态

# 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 %>


0

使用哈希。我将我的文件放在config / initializers / us_states.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}" %>

you️当您在应用程序中支持多种语言时,这实际上与国家和语言代码一起使用效果更好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.