2016-05-14 74 views
1

问题: 我需要过滤一组单元的集合,其基础是选择一组组织。Rails 4:如何通过AJAX更新基于另一个collection_select的collection_select?

在选择组织,则单位下拉菜单应只刷新,显示单位属于知情组织

我检查了这些问题:

而且这些单证:

这是到目前为止我的代码:

模式

class Organization < ActiveRecord::Base 
    has_many :units 
    has_many :projects, through: :units 
end 
class Unit < ActiveRecord::Base 
    belongs_to :organization 
    has_many :projects 
end 
class Project < ActiveRecord::Base 
    belongs_to :organizaton 
    has_one :organization, through: :unit 
end 

查看 应用程序/视图/项目/ _form.html.erb

<%= form_for(@project) do |f| %> 

    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :description %><br> 
    <%= f.text_area :description %> 
    </div> 
    <div class="field"> 
    <%= f.label :organization_id %><br> 
    <%= f.collection_select :organization_id, Organization.all, :id, :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :unit_id %><br> 
    <%= f.collection_select :unit_id, Unit.all.where(organization_id: :organization_id), :id, :name %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

控制器 项目控制器

def new 
    @project = Project.new 
end 

def project_params 
    params.require(:project).permit(:name, :description, :organization_id, :unit_id) 
end 

我怎样才能使这项工作?

回答

6

我做到了,该解决方案是非常简单的,但由于缺乏这方面简单的问题更新材料制成它更大一个苦差事比它应该有:

的config/routes.rb中

get 'filter_units_by_organization' => 'projects#filter_units_by_organization' 

控制器/ projects_controller.rb

def filter_units_by_organization 
    @filtered_units = Unit.where(organization_id: params[:selected_organization]) 
end 

层的意见/项目/ filter_units_by_organization.js.erb

$('select#project_unit_id').html('<%= j options_from_collection_for_select(@filtered_units, :id, :name) %>'); 

资产/ Java脚本/ application.js中

$(function() { 
    $("select#project_organization_id").on("change", function() { 
     $.ajax({ 
      url: "/filter_units_by_organization", 
      type: "GET", 
      data: { selected_organization: $("select#project_organization_id").val() } 
     }); 
    }); 
}); 

的意见/项目/ _form.html.erb

<div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :description %><br> 
    <%= f.text_area :description %> 
    </div> 
    <div class="field"> 
    <%= f.label :organization_id %><br> 
    <%= f.collection_select :organization_id, Organization.all, :id, :name, { prompt: 'Please select' } %> 
    </div> 
    <div class="field"> 
    <%= f.label :unit_id %><br> 
    <%= f.collection_select :unit_id, Unit.all.where(organization_id: :organization_id), :id, :name %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
1

而不是在projects表上放置一个副本organization_id您应该设置关系经历单位模型。

class Organization < ActiveRecord::Base 
    has_many :units 
    has_many :projects, through: :units 
end 

class Unit < ActiveRecord::Base 
    belongs_to :organization 
    has_many :projects 
end 

class Project < ActiveRecord::Base 
    belongs_to :unit 
    has_one :organizaton, through: :unit 
end 

这就避免了尴尬的问题,你必须以确保单位和项目有相同的organizaton_id

这也意味着您在创建项目时不再需要输入来选择组织 - 只是单位。

+1

如果您仍希望组织为用户选择能够缩小选项范围需要实现它作为ajax调用。但是,这本身就是整个教程,如果你是新手入门,那么以后可能会更好。 – max

+0

感谢@max的提醒,我会用你的答案重构代码:)关于ajax,我想这就是我的意图,我会重新回答这个问题。我在rails上使用ajax做了一些基本的事情,比如livesearch过滤器,排序和分页,还设置了视图模板来响应模态,但是我对JS和Rails之间“对话”的了解非常有限,您知道任何我可以更多地了解它的地方?谢谢 –

+1

我不使用'js.erb'或内置'remote:true'选项。恕我直言,它只是导致服务器端和客户端逻辑和糟糕的API的总clusterfuck。它是铁轨中最糟糕的部分之一。我只使用普通的旧jquery ajax处理程序和来自控制器的JSON响应。 – max