2

我正在尝试在我的 rails 应用程序中实现级联选择表单,以便城市更新区域选项并且区域更新社区选项。但是,使用我在下面实现的解决方案,所有三个字段都返回所有选项,而不管父字段的选择如何。因此,例如,它显示所有社区,无论选择城市或区域,城市也不会更新区域选项。

我的代码看起来不错,并且关联(我认为)都已正确设置。

城市.rb

has_many :areas

面积.rb

attr_accessible :name, :city_id
belongs_to :city
has_many :neighborhoods

邻里.rb

attr_accessible :name, :area_id
belongs_to :area

我的表单代码:

<%= form_for @user do |f| %>
    <p>City:</p>
    <%= f.collection_select(:city_id,  @cities,  :id, :name, {:prompt   => "Select a City"}, {:id => 'cities_select'}) %>

    <p>City area:</p>
    <%= f.collection_select(:area_id, @areas, :id, :name, {:prompt   => "Select an Area"}, {:id => 'areas_select'}) %>

    <p>Neighborhood:</p>
    <%= f.collection_select(:neighborhood_id, @neighborhoods, :id, :name, {:prompt   => "Select a Neighborhood"}, {:id => 'neighborhoods_select'}) %>

控制器:

    def update_areas
      # updates artists and songs based on genre selected
      city = City.find(params[:city_id])
      # map to name and id for use in our options_for_select
      @area = city.areas.map{|a| [a.name, a.id]}.insert(0, "Select an Area")
      @neighborhoods = city.neighborhoods.map{|s| [s.title, s.id]}.insert(0, "Select a neighborhood")
    end

    def update_neighborhoods
      # updates songs based on artist selected
      area = Area.find(params[:area_id])
      @neighborhoods = area.neighborhoods.map{|s| [s.title, s.id]}.insert(0, "Select a neighborhood")
    end

update_neighborhoods.js.erb:

$('#neighborhoods_select').html("<%= escape_javascript(options_for_select(@neighborhoods)) %>");

update_areas.js.erb:

$('#areas_select').html("<%= escape_javascript(options_for_select(@areas)) %>");
$('#neighborhoods_select').html("<%= escape_javascript(options_for_select(@neighborhoods)) %>");

控制器:

def new
    if user_signed_in?
        @building = Building.new
        @cities  = []
        @areas = []
        @neighborhoods = Neighborhood.all
    else
        redirect_to new_user_session_path
    end
end

表单所在的 new.html.erb 页面中的 Javascript:

<script>
$(document).ready(function() {
$('#cities_select').change(function() {
  $.ajax({
    url: "<%= update_areas_path %>",
    data: {
      city_id : $('#cities_select').val()
    },
    dataType: "script"
  });
});
$('#areas_select').change(function() {
  $.ajax({
    url: "<%= update_neighborhoods_path %>",
    data: {
      area_id : $('#areas_select').val()
    },
    dataType: "script"
  });
});
});
</script>

路线.rb:

 get '/users/update_areas', :as => 'update_areas'
 get '/users/update_neighborhoods', :as => 'update_neighborhoods'

谁能帮我解决这个问题?

更新 - -

现在我已经让级联 collection_select 表单工作了,但是当我提交表单时,我收到以下错误:

undefined method `map' for nil:NilClass
Extracted source (around line #29):
<%= f.collection_select(:city_id,  @cities,  :id, :name, {:prompt   => "Select a City"}, {:id => 'cities_select'}) %>

为什么会这样?在我看来,我已尝试将其更改为“City.all”而不是@cities,但随后@areas 出现相同的错误...

4

1 回答 1

1

很难找出 bug,所以我在 github 上创建了一个应用程序:https ://github.com/brookzhang/cascading

答案是 :

当您谈论“所有三个字段都返回所有选项,无论父字段的选择如何。”时,这是一个失败,而不是一个成功的响应。所以 UI 将保持原样。

1.@neighborhoods = city.neighborhoods.map{|s| [s.title, s.id]}.insert(0, "选择一个社区")

City 和 Neighborhood 之间没有关系,这里发生错误。

=> @neighborhoods = Neighborhood.where(:area_id => city.areas.each{|a| a.id}).map{|s| [s.name, s.id]}.insert(0, "选择一个社区")

2.@neighborhoods = city.neighborhoods.map{|s| [s.title, s.id]}.insert(0, "选择一个社区")

邻居有名为“名称”的字段,而不是“标题”

英语很差,有关更多信息,请参阅我的 github,它工作正常。

于 2013-05-12T08:50:21.347 回答