使用Soulmate和Redis进行自动完成时未定义的方法`downcase'

时间:2014-03-05 00:17:58

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

我正在努力为产品制作text_field_tag自动完成功能。为此,我使用Soulmate并遵循此tutorial,但在实现代码并将其更改为我的应用程序后遇到了问题。当我转到localhost:3000/sm时,灵魂伴侣服务器确实正常运行。现在我的代码是这样的:

产品型号

class Product < ActiveRecord::Base
  after_save :add_to_soulmate
  before_destroy :remove_from_soulmate

  def self.search(name)
    products = Soulmate::Matcher.new("product").matches_for_term(name)
    products.collect { |p| { "id" => p["id"], "name" => p["term"] } }
  end

  private

  def add_to_soulmate
    loader = Soulmate::Loader.new('product')
    loader.add('term' => name, 'id' => self.id)
  end

  def remove_from_soulmate
    loader = Soulmate::Loader.new('product')
    loader.remove('id' => self.id)
  end
end

产品控制器

def autocomplete
  render :json => Product.search(params['name'])
end

Products.js.coffee

$(document).on "keypress", "#search-input", ->
  $("#product-results").html("")

  $.get "/products/autocomplete",
    name: $("#search-input").val(),
    ((data) ->
      count = 0

      while count <= data.length - 1
        product = data[count]
        $("#product-results").append("<li id='product-#{ product.id }'> #{ product.name } </li>")
        count++
    ), "json"

路线

  resources :products do
    collection do
      get 'autocomplete'
    end
  end

  mount Soulmate::Server, :at => '/sm'

产品/索引视图

<div id='product-results'>
  <%= text_field_tag :product_name, nil, autocomplete_off: 'off', id: 'search-input' %>
</div>

在我输入产品的视图中,整个字段只是完全消失,如果我查看服务器日志,则会出错:

NoMethodError - undefined method `downcase' for nil:NilClass:

当我转到:localhost:3000 / products / autocomplete

时,会出现同样的错误

所以,我迷路了,我该怎么办?

修改

NoMethodError - undefined method `downcase' for nil:NilClass:
  soulmate (1.0.0) lib/soulmate/helpers.rb:17:in `normalize'
  soulmate (1.0.0) lib/soulmate/matcher.rb:8:in `matches_for_term'
  app/models/product.rb:31:in `search'
  app/controllers/products_controller.rb:5:in `autocomplete'
  actionpack (4.0.2) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.0.2) lib/abstract_controller/base.rb:189:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.0.2) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
  activesupport (4.0.2) lib/active_support/callbacks.rb:423:in `_run__784868843__process_action__callbacks'
  activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.2) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.0.2) lib/active_support/notifications.rb:159:in `block in instrument'
  activesupport (4.0.2) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.0.2) lib/active_support/notifications.rb:159:in `instrument'
  actionpack (4.0.2) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
  activerecord (4.0.2) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.0.2) lib/abstract_controller/base.rb:136:in `process'
  actionpack (4.0.2) lib/abstract_controller/rendering.rb:44:in `process'
  actionpack (4.0.2) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.0.2) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.0.2) lib/action_controller/metal.rb:231:in `block in action'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:80:in `call'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:48:in `call'
  actionpack (4.0.2) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `each'
  actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:680:in `call'
  warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.3) lib/warden/manager.rb:34:in `catch'
  warden (1.2.3) lib/warden/manager.rb:34:in `call'
  rack (1.5.2) lib/rack/etag.rb:23:in `call'
  rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
  rack (1.5.2) lib/rack/head.rb:11:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/flash.rb:241:in `call'
  rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/cookies.rb:486:in `call'
  activerecord (4.0.2) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.0.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
  activerecord (4.0.2) lib/active_record/migration.rb:369:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.0.2) lib/active_support/callbacks.rb:373:in `_run__747342270__call__callbacks'
  activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.2) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/reloader.rb:64:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  better_errors (1.1.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (1.1.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (1.1.0) lib/better_errors/middleware.rb:56:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.0.2) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.0.2) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.0.2) lib/active_support/tagged_logging.rb:67:in `block in tagged'
  activesupport (4.0.2) lib/active_support/tagged_logging.rb:25:in `tagged'
  activesupport (4.0.2) lib/active_support/tagged_logging.rb:67:in `tagged'
  railties (4.0.2) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack-contrib (1.1.0) lib/rack/contrib/runtime.rb:18:in `call'
  activesupport (4.0.2) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/static.rb:64:in `call'
  rack-contrib (1.1.0) lib/rack/contrib/sendfile.rb:105:in `call'
  railties (4.0.2) lib/rails/engine.rb:511:in `call'
  railties (4.0.2) lib/rails/application.rb:97:in `call'
  rack (1.5.2) lib/rack/content_length.rb:14:in `call'
  unicorn (4.8.2) lib/unicorn/http_server.rb:572:in `process_client'
  unicorn (4.8.2) lib/unicorn/http_server.rb:666:in `worker_loop'
  unicorn (4.8.2) lib/unicorn/http_server.rb:521:in `spawn_missing_workers'
  unicorn (4.8.2) lib/unicorn/http_server.rb:140:in `start'
  unicorn-rails (1.1.0) lib/unicorn/rails.rb:24:in `run'
  rack (1.5.2) lib/rack/server.rb:264:in `start'
  railties (4.0.2) lib/rails/commands/server.rb:84:in `start'
  railties (4.0.2) lib/rails/commands.rb:76:in `block in <top (required)>'
  railties (4.0.2) lib/rails/commands.rb:71:in `tap'
  railties (4.0.2) lib/rails/commands.rb:71:in `<top (required)>'
  bin/rails:4:in `require'
  bin/rails:4:in `<main>'

1 个答案:

答案 0 :(得分:1)

看起来你并没有向Soulmate发送一个字符串。在第31行的search方法的产品型号中,检查您的name是否为零。

使用pry gem将有助于此。

根据评论,访问localhost:3000/products/autocomplete?name=somesearchterm并查看错误是否仍然存在,因为这应确保您拥有有效名称。

您可能希望检查一个空字符串,以确保此问题在将来不会发生:

产品控制器

def autocomplete
  name = params['name'] 
  if name.present?
    render :json => Product.search(name)
  else
    render :json => {}
  end
end

您还需要为前端提供数据,就像在教程中一样:

在javascript中:

while count <= data.length - 1
        contact = data[count]
        $("#contact-results").append("<li id='contact-#{contact.id}'>#{contact.name} - #{contact-number}</li>")
        count++

在控制器中:

contacts.collect { |c| { "id" => c["id"], "name" => c["term"], "number" => c["data"]["number"], "email" => c["data"]["email"] } }