2013-05-12 30 views
2

我试图在我的rails应用程序中实现级联选择表单,以便城市更新区域选项,并更新区域选项。但是,使用下面实现的解决方案,无论父字段的选择如何,所有三个字段都会返回所有选项。例如,它显示所有街区,而不考虑城市或地区选择,城市也不更新区域选项。Rails - 级联选择表单不互相更新并显示所有结果

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

city.rb

has_many :areas 

area.rb

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

neighborhood.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 

的Javascript在我的新。 html.erb页面在表格所在:

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

的routes.rb:

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

谁能帮我这个?

UPDATE ----

现在我已经得到了级联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中得到了相同的错误...

回答

1

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

答案是:

当你谈论“三个字段返回所有的选项,而不管父场的选择。”,这是一个失败,而不是成功的响应。所以用户界面将保持与以前一样。

1. @neighborhoods = city.neighborhoods.map {| s | [s.title,s.id]}。插入(0,“选择邻居”)

城市和邻居之间没有关系,这里发生了错误。

=> @neighborhoods = Neighborhood.where(:area_id => city.areas.each {| a | a.id})。map {| s | [s.name,s.id]}。insert(0,“Select a neighborhood”)

2. @neighborhoods = city.neighborhoods.map {| s | [s.title,s.id]}。插入(0, “选择一个社区”)

附近有一个名为 “名”,而不是 “标题”

很差,英语,了解更多信息领域,请看我的github,它工作正常。

+0

感谢您创建示例应用,真的很有用!看起来我的路线不正确,'标题'与'名字'的区别也让我尴尬。非常感激! – Zephyr4434 2013-05-12 19:39:16

+0

submited后,表单将被发布到创建/更新操作,这将永远不会再次呈现表单。怎么会发生在“<%= f.collection_select()%>”? – brookz 2013-05-13 07:07:46

+0

请将您的代码添加到https://github.com/brookzhang/cascading,也许这将清楚整个代码。 – brookz 2013-05-13 07:14:50