Ruby on Rails国家/州选择Enigma

我正在努力实现一些看似非常简单的事情,而且我已经在这几天打了我的脑袋。

我想要的最终结果是国家选择下拉列表,与状态选择下拉列表相关联,这样当选择给定国家/地区时,IF状态已知,那么这些状态将显示在选择下拉列表中,如果该国家/地区不知道任何州,然后会显示文本字段。

我觉得我快到了。 此时,接口实际上将根据人员的国家生成状态列表,除非它拒绝动态更新下拉列表。

我的视图中收集国家和州位置的部分看起来像:

# _person_setup.html.erb  *
'width: 200px', :id => 'country_select', :onchange => remote_function( :url => {:action => 'update_states'}, :with => "'country='+value")} %>

'states', :object => Carmen::states( Carmen::country_code( @person.country)), :locals => {:form => f} %>

DIV中引用的部分如下:

  # _states.html.erb  *
*

最后,控制器代码用于动态更新状态列表:

 def update_states puts "Attempting to update states..." q = params[:country] states = Carmen::states(Carmen::country_code(q)) puts "Country = #{q}, states = #{states.collect{|s| s[0]}.join(", ")}." render :update do |page| page.replace_html "states_div", :partial => 'states', :object => states, :locals => {:form => form_for(@person)} end puts "OK" end 

现在,在适当的时间调用此代码并生成适当的状态列表。 例如,当用户点击澳大利亚时,“尝试更新州…国家=澳大利亚,州=澳大利亚首都直辖区,新南威尔士州,北领地,昆士兰州,南澳大利亚州,塔斯马尼亚州,维多利亚州,西澳大利亚州”出现在服务器进程。 但是它不会更新页面,也不会在最后打印“确定”。 简而言之,失败的路线无疑是

 page.replace_html "states_div", :partial => 'states', :object => states, :locals => {:form => form_for(@person)} 

请注意,用此替换此行

 page.replace_html 'states_div', "is it working" 

正确地替换div,但当然没有任何有用的东西。

有人可以帮我理解这里发生了什么吗?

看起来您假设@person变量仍然可以从原始操作中获得。 这可以通过当前人员的filter设置,但您不会在您的问题中显示。

如果你确实需要再次查找@person,我必须在你的remote_function中传递id。

Ryan Bates有一个Railscast,它显示了如何为产品选择类别或通过键入名称来创建新类别。 这听起来与您所拥有的情况类似,因此您可能需要查看它: 通过文本字段创建模型 。

这花了我一整天才弄清楚至少会“起作用”的东西。 我也在使用Carmen并且还在form_for模型表单中弄乱了select标签(实际上,fields_for嵌套在forms_for中……这增加了额外的复杂性)。

我认为有一个更好的解决方案,但这对我有用。 select需要由表单引用,但选项不需要。 因此,第一次,我使用Carmen state_select方法正确填充选择标记和所有嵌套选项标记。 第二次,我只是替换选项。 看一看:

在视图中,我选择使用observe_field方法,因为除了更新状态(其他一些本地化更改)之外我还做其他事情,但这也适用于remote_function和其他方法:

 <%= address_form.country_select :country, {:prompt => "--Select One--"} %> 

不要被id(user_address_attributes_country)搞糊涂,这只是我愚蠢的forms_for / fields_for实现)

 <%= observe_field :user_address_attributes_country, :url => { :action => :changecountry }, :with => 'new_country' %> <%= address_form.state_select :state, @user.address.country, {:prompt => "--Select One--"}, :style => 'width: 90px' %> 

然后在我的控制器中,它看起来像这样:

 def changecountry c = params[:new_country] respond_to do |format| format.html format.js { render :update do |page| page['user_address_attributes_state'].innerHTML = \ "" + state_options_for_select(nil, c) end } end end 

注意: state_options_for_select也来自Carmen。 我无法让它工作,除非我把它放在respond_to块中,我认为视图助手可用。 另外,我硬编码user_address_attributes_state ,这是我在视图中从form_for / fields_for address_form.state_select渲染调用生成的嵌套id。

我希望这有帮助。 如果有人能做得更好,请相信我,我都是耳朵。 我会及时更改设计……但是需要今天才有效的东西,这是我能在有限的时间内找到的最好的东西。