【问题标题】:Rails 4: How to update a collection_select based on another collection_select through AJAX?Rails 4:如何通过 AJAX 基于另一个 collection_select 更新一个 collection_select?
【发布时间】:2016-09-10 20:33:00
【问题描述】:

问题: 我需要根据Organizations 集合的选择来过滤Units 集合。

选择组织后,单位下拉菜单应刷新以仅显示属于知情组织单位 /强>。

我已经检查了这些问题:

还有这些文件:

这是我目前的代码:

模型

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

观看次数 app/views/projects/_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

我怎样才能做到这一点?

【问题讨论】:

    标签: ruby-on-rails ajax ruby-on-rails-4


    【解决方案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 的尴尬问题。

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

    【讨论】:

    • 如果您仍然希望组织为用户选择能够缩小您需要将其实现为 ajax 调用的选项。然而,这本身就是整个教程,如果您是 Rails 新手,最好留到以后再说。
    • 感谢@max 的提醒,我会用你的答案重构代码:) 关于 ajax,我想这就是我真正的意图,我会改写这个问题。我已经用 ajax on rails 做了一些基本的事情,比如实时搜索过滤器、排序和分页,还设置了视图模板以响应模式,但是我对 JS 和 Rails 之间的“对话”的了解非常有限,是吗?知道有什么地方可以让我了解更多吗?谢谢
    • 我不使用js.erb 或内置的remote: true 选项。恕我直言,它只会导致服务器端和客户端逻辑以及糟糕的 API 的完全混乱。它是铁轨最糟糕的部分之一。我只使用普通的旧 jquery ajax 处理程序以及来自控制器的 JSON 响应。
    【解决方案2】:

    我做到了,解决方案非常简单,但缺乏关于这个简单问题的更新材料使得它变得比它应该做的更麻烦:

    config/routes.rb

     get 'filter_units_by_organization' => 'projects#filter_units_by_organization'
    

    controllers/projects_controller.rb

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

    views/projects/filter_units_by_organization.js.erb

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

    assets/javascripts/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() }
            });
        });
    });
    

    views/projects/_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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 2014-12-08
      • 2016-07-31
      • 2016-11-22
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      相关资源
      最近更新 更多