我假设你想这无需重新加载页面发生的呢?那么你不会绕过一些JavaScript。这里的一般工作流程:
- 当类别下拉列表改变时,发送一个Ajax请求将与JavaScript的响应,并插入正确的值到子类别下拉菜单。
为了这个例子我只是假设你的表单(属于一个类别的模型)是一个帖子。你似乎没有提到这个模型。
让我们试试这个:
的意见/职位/ _form:
我将包裹的子类别SELCT箱在subcategories_select
DIV,这使我们后来更换整个内容。
<%= f.collection_select :category_id, Category.all, :id, :name, { prompt: "Choose a category" }, id: "category_id" %>
<div id="subcategories_select">
<%= f.collection_select :subcategory_id, Subcategory.all, :id, :name, { prompt: "Choose a subcategory" }, { disabled: true } %>
</div>
资产/ Java脚本/ posts.js.erb
# select the element to watch for changes
$('form').on('change', '#category_id'), function() {
var category_id = $(this).val(); # save the category_id set in the first dropdown
$.ajax({
url: "/categories/" + category_id + "/get_subcategories", # a custom route, see routes.rb further down
type: "GET",
dataType: "script", # we expect a response in js format
data: { "category_id": category_id } # the only value we will need to get the subcategories
});
});
配置/路线。RB
# we need a custom route for our get_subcategories action
resources :categories do
member do
get :get_subcategories, defaults: { format: "js" }
end
end
控制器/ posts_controller.rb
重要:我认为一个类别的has_many子类别和子类别具有CATEGORY_ID,其meansbelong_to一个类别。如果这不是以下将是没有意义的。
# our custom controller action
def get_subcategories
@subcategories = Subcategory.where(category_id: params[:category_id])
end
应用程序/视图/职位/ get_subcategories.js.erb
在这里,我们将取代我们subcategories_select div的内容并插入一个collection_select用适当的选项。
$('#subcategories_select').html("<%= j collection_select(:post, :category_id, @subcategories, :id, :title), { prompt: 'Select subcategory...' }, { disabled: false } %>");
请注意,我这样做是从我的头顶,所以有可能是错误的,但这是动态填充选择框,或在页面上一般改变什么而无需重新加载一个方法。
@MikeMcCallen前端积极与后端通信的更多细节。所以来自'前端'的函数在'后端'调用函数,然后它接收结果并处理它们。我建议你阅读更多关于ajax,并考虑网络的工作原理;) –
我一定误解了你的问题。在我看来,当用户在第一个选项('选择类别')中选择一个选项时,您试图更改第二个下拉菜单('选择一个子类别')的内容。看起来你试图在服务器端实现这一点,在某些圈子里,这被认为是错误的。 每当用户更改第一个菜单中的选项,然后使用该响应来填充第二个菜单中的选项时,您可能会尝试的是对您的控制器执行AJAX调用。但是,这又有点不正统。 –
这绝对可以在rails中实现。使用简单的json API。除非我误解你的回答。 –