在 Rails 4 中使用 AJAX 和两个 select 框

Using AJAX with two select boxes in Rails 4

我有一个包含两个 select 框的视图:公司和员工。两者都有一个空白选项,当一家公司被 selected 时,它会根据 selected 公司填充员工。这很好用。我的问题是,当我提交一个验证失败的表单(如预期的那样)时,一旦 'new' 视图在 extensions#create 中再次呈现,我再次 select 一家公司,我的 'get' AJAX 调用已从 /servers/1/extensions/get_company_employees(正确) 更改为 /servers/1/get_company_employees(不正确) 并返回 404 Not found .为什么会发生这种情况,我应该如何补救?所有相关代码如下

routes.config

resources :servers do
  scope module: 'servers' do
    resources :extensions, shallow: true
  end
end

# Ajax call
get 'servers/:id/extensions/get_company_employees', to: 'servers/extensions#get_company_employees', as: 'get_company_employees'

app/controllers/servers/extensions_controller.rb

class Servers::ExtensionsController < ApplicationController

  def get_company_employees
    @server = Server.find(params[:id])
    @extension = @server.extensions.build
    @path = [@server, @extension]

    @companies = Company.all
    @employees = Employee.where("company_id = ?", params[:company_id])
    respond_to do |format|
      format.js
    end
  end

  def new
    @server = Server.find(params[:server_id])
    @extension = @server.extensions.build
    @path = [@server, @extension]

    @companies = Company.all
    @employees = Employee.none
  end

  def create
    @server = Server.find(params[:server_id])
    @extension = @server.extensions.build(extension_params)
    @extension.password = "pass"
    if @extension.save
      flash[:success] = "Successfully created extension"
      redirect_to @extension
    else
      @path = [@server, @extension]
      @companies = Company.all
      @employees = Employee.none
      flash.now[:error] = "Failed to create extension"
      render "new"
    end
  end

  private
    def extension_params
      params.require(:extension).permit(:value, :password, :employee_id, :server_id, :phone_id)
    end
end

app/views/servers/extensions/_form.html.erb

<%= form_for(@path) do |f| %>
  <p>
    <%= label_tag(:company) %>
    <%= select_tag "company", options_from_collection_for_select(@companies, "id", "name"), include_blank: "Select a company" %>
  </p>
  <p>
    <%= f.label(:employee) %>
    <%= f.collection_select :employee_id, @employees, :id, :full_name, include_blank: "Select an employee" %>
  </p>
  <p>
    <%= f.submit "Submit" %>
  </p>
<% end %>

app/views/servers/extensions/get_company_employees.js.coffee

$("#extension_employee_id").empty()
.append("<option>Select an employee</option>")
.append("<%= j options_from_collection_for_select(@employees, :id, :full_name) %>")

app/assets/javascripts/servers/extensions.咖啡

$ ->
  $(document).on 'page:load', '#company', (evt) ->
    $.ajax 'get_company_employees',
      type: 'GET'
      dataType: 'script'
      data: {
        company_id: $("#company option:selected").val()
      }

  $(document).on 'change', '#company', (evt) ->
    $.ajax 'get_company_employees',
      type: 'GET'
      dataType: 'script'
      data: {
        company_id: $("#company option:selected").val()
      }

这是因为您现在已经在 ajax 调用中指定了完整的 URL 在这两种情况下都应该是这样的。

$.ajax "/servers/"+ id +"/extensions/get_company_employees',
  type: 'GET'
  dataType: 'script'
  data: {
    company_id: $("#company option:selected").val()
  }
// store and fetch id attribute from page in any of the dom element

理想情况下,您应该为 ajax 调用编写一个函数,可以在任何需要的地方调用它,并且可以减少代码冗余。