This question already has an answer here:
How to populate a Rails dropdown menu with a json array
(1个答案)
4年前关闭。
我有一个包含学校和专业的Rails数据库。一旦用户选择了他的学校,我只想用来自相应学校的专业来填写专业的下拉菜单。目前,我有两个工作下拉菜单,但您可以看到它们只是选择了所有值。为此,我将需要Json/Ajax/JavaScript吗?如果是,该如何实现呢?
(1个答案)
4年前关闭。
我有一个包含学校和专业的Rails数据库。一旦用户选择了他的学校,我只想用来自相应学校的专业来填写专业的下拉菜单。目前,我有两个工作下拉菜单,但您可以看到它们只是选择了所有值。为此,我将需要Json/Ajax/JavaScript吗?如果是,该如何实现呢?
<div class="field">
<%= f.label :school_id %><br>
<%= f.collection_select :school_id, School.order(:name),:id,:name, include_blank: false %>
</div>
<div class="field">
<%= f.label :major_id %><br>
<%= f.collection_select :major_id, Major.order(:name),:id,:name, include_blank: false %>
</div>
最佳答案
编辑
当前的解决方案是对每个下拉选择使用异步请求。假设您的选择总语料量很小(比如说原来的
好了,经过大量搜索之后,我收到了一个有效的AJAX请求(我将在此处发布以供后代引用)。
在我的数据库中创建新类(class)时,必须有学校和专业外键,它们必须为非空值。这是下拉菜单
<!-- app/views/courses/_form.html.erb -->
<div class="field">
<%= f.label :school_id %><br>
<%= f.collection_select :school_id, School.order(:name),:id,:name, {include_blank: false},{:id=>'school_id_select'} %>
</div>
<div class="field">
<%= f.label :major_id %><br>
<%= f.collection_select :major_id, [],:id,:name, {include_blank: false},{:id=>'major_id_select'} %>
</div>
现在,HTML已经启动,我们需要一些JavaScript(和jQuery)来处理AJAX请求//app/assests/javascripts/courses.js (note this was generated as a .coffee file, which I changed to .js as I don't know CoffeeScript
console.log('loaded courses.js')//check that the file is loaded
$(document).on('change','#school_id_select', function () {//change majors when user changes school
load_majors_from_school_dropdown();
});
$(document).ready(load_majors_from_school_dropdown);//populate majors when page loads with first school
function load_majors_from_school_dropdown(){
var request = "/majors/find_majors_given_school_id?school_id=" //access controller of interest
+ $('#school_id_select').val();
var aj = $.ajax({
url: request,
type: 'get',
data: $(this).serialize()
}).done(function (data) {
change_majors(data);//modify the majors' dropdown
}).fail(function (data) {
console.log('AJAX request has FAILED');
});
};
//modify the majors' dropdown
function change_majors(data) {
$("#major_id_select").empty();//remove all previous majors
for(i = 0;i<data.length;i++){
$("#major_id_select").append(//add in an option for each major
$("<option></option>").attr("value", data[i].id).text(data[i].name)
);
}
};
注意“request”变量。这表示将处理请求的 Controller 和操作。现在我们必须做到。我的Major Controller 已经存在,因此我们只需要添加操作即可。首先添加 Action 的路由,以使Rails服务器知道该 Action 。#config/routes.rb
Rails.application.routes.draw do
#...
get 'majors/find_majors_given_school_id'
#...
end
现在在主 Controller 中创建 Action #app/controllers/majors_controller.rb
#custom action for AJAX/JSON calls. Note this can be done multiple ways
def find_majors_given_school_id
school_id = params[:school_id]#utilizes the url to extract school_id ".../find_majors_given_school_id?school_id=123123"
puts "THIS IS MY SCHOOL ID :: #{school_id}"#view this in teminal
majors = Major.search_for_school_id(school_id).as_json#query the model for the data and convert it to a hash using as_json
puts "THESE ARE MY MAJORS IN A HASH :: #{majors}"
respond_to do |format|
format.json {
render json: majors
}
end
end
最后,我们必须创建查询以在我们的模型中提取此信息。#app/models/major.rb
class Major < ActiveRecord::Base
has_many :courses, dependent: :destroy
belongs_to :school, :foreign_key => "school_id"
def self.search_for_school_id(id)
where("school_id = ?",id)
end
#...
end
我认为这就是一切。当然,还有其他方法可以实现这一点,但是这种方法对我有用。祝你好运!