使用 Rails 的控制器中的路由不正确 4 自动完成

Incorrect routing in controller using Rails 4 Autocomplete

我按照本教程 (http://www.yoniweisbrod.com/autocomplete-magic-with-rails/) 使用 jQuery-ui 的自动完成功能,但是当我尝试使用文本字段进行搜索时,它会路由到控制器的 show 方法而不是 autocomplete_ingredient_name 方法。

这是我的表单代码:

<%= form_tag(cocktail_path(1), :method => 'get', :class => "search_form", :remote => true) do %>
  <%= label_tag(:query, "Choose ingredients:") %>
  <%= autocomplete_field_tag(:query, params[:query], autocomplete_ingredient_name_cocktails_path, {class: "search-query", placeholder: "", type: "search"}) %>
  <% @ingredients.each do |ingredient| %>
    <%= hidden_field_tag "ingredients[]", ingredient.name %>
  <% end %>
  <%= submit_tag("Search") %>
<% end %>

还有我的控制器。

class CocktailsController < ApplicationController
  autocomplete :ingredient, :name

  def index
    @cocktails = []
    @ingredients = []
  end

  def autocomplete_ingredient_name
    @ingredients = Ingredient.order(:name).where("name LIKE ?", "'%#{params[:query]}%'")
    respond_to do |format|
      format.html
      format.json { 
        render json: @ingredients.map(&:name)
      }
    end
  end

  def show
    hash = {}
    @cocktails = []
    @ingredients = Ingredient.all.map {|ingredient| ingredient}
    @ingredients.select! {|ingredient| ingredient.name.downcase.include?(params[:query])}
    if params[:ingredients] 
      old_ingredients = []
      params[:ingredients].each do |ing|
        old_ingredients << Ingredient.find_by(name: ing)
      end
      cocktails = @ingredients.map {|ingredient| ingredient.cocktails }.flatten
      old_cocktails = old_ingredients.map {|ingredient| @cocktails << ingredient.cocktails }.flatten!
      old_cocktails.each do |cocktail|
        hash[cocktail] = 1
      end
      cocktails.each do |cocktail|
        if hash.has_key?(cocktail)
          @cocktails << cocktail
        end
      end
      @cocktails = @cocktails.uniq.flatten
    else
      @cocktails = @ingredients.map {|ingredient| ingredient.cocktails }.flatten
    end

  end


end

这是来自我的服务器的消息,转到 CocktailsController#show 方法,而不是自动完成方法。

Started GET "/cocktails/autocomplete_ingredient_name?term=mi" for ::1 at 2015-10-12 15:32:21 -0500
Started GET "/cocktails/autocomplete_ingredient_name?term=mi" for ::1 at 2015-10-12 15:32:21 -0500
Processing by CocktailsController#show as JSON
Processing by CocktailsController#show as JSON
  Parameters: {"term"=>"mi", "id"=>"autocomplete_ingredient_name"}
  Parameters: {"term"=>"mi", "id"=>"autocomplete_ingredient_name"}
  Ingredient Load (8.6ms)  SELECT "ingredients".* FROM "ingredients"
  Ingredient Load (8.6ms)  SELECT "ingredients".* FROM "ingredients"
Completed 500 Internal Server Error in 38ms (ActiveRecord: 8.6ms)
Completed 500 Internal Server Error in 38ms (ActiveRecord: 8.6ms)

TypeError (no implicit conversion of nil into String):
  app/controllers/cocktails_controller.rb:25:in `include?'
  app/controllers/cocktails_controller.rb:25:in `block in show'
  app/controllers/cocktails_controller.rb:25:in `select!'
  app/controllers/cocktails_controller.rb:25:in `show'



TypeError (no implicit conversion of nil into String):
  app/controllers/cocktails_controller.rb:25:in `include?'
  app/controllers/cocktails_controller.rb:25:in `block in show'
  app/controllers/cocktails_controller.rb:25:in `select!'
  app/controllers/cocktails_controller.rb:25:in `show'

该代码应该创建一个 jQuery-ui 下拉菜单来预测您正在搜索的内容,但该下拉菜单从未显示,并且立即 returns 出现 500 错误。

任何关于为什么这不是路由到正确方法的想法将不胜感激!

这可能是因为路由错误,即您的 GET "/cocktails/autocomplete_ingredient_name?term=mi" 指令由 /config/routes.rb 文件中的错误条目处理。

确保处理自动完成过程的路由在处理鸡尾酒控制器的显示操作的路由之前定义。 由于后者通常采用 get 'cocktails/:id' 形式,因此 URI 的 'autocomplete_ingredient_name' 部分会影响到 :id 组件,并且处理将委托给控制器的 show 操作说id.

自动完成路由已定义,因为表单中的 autocomplete_ingredient_name_cocktails_path 指令会生成格式正确的 URI;所以我认为这只是一个优先级问题。

然而,您还有另一个潜在问题:您的自动完成查询参数在您的请求中是 'term',但在您的控制器操作中是 'query'。他们应该有一个相同的名字。