字符串上的JSON输出导致NoMethodError - #string:***>的未定义方法`id':

时间:2016-07-18 16:08:38

标签: ruby-on-rails ruby json string autocomplete

我有一个像这样的字符串数组。

trans_names = ["UBER US JUL01 YO3SW CA 16184", 
               "UBER US JUL01 HVRD2 CA 16186", 
               "UBER US JUL01 LIORT CA 16184", 
               "UBER US JUN26 UCF2Z CA 16180", 
               "UBER US JUN27 EZOF5 CA 16180", 
               "UBER US JUN25 BM3LO CA 16179",  
               "UBER US JUN23 5RNBI CA 16177"]

当我在数组中搜索像“UBE”这样的单词时,它应该返回我正在输入的单词的json。所以它应该返回“UBER”只是单词“UBER”而不是整个字符串,只有1个uber实例而不是7个实例。这是我的控制器方法

   def get_autocomplete_items(params)
     @transaction = current_user.transaction
     @trans_array = @transaction.trans_names.find_all { |x| /#{Regexp.escape(params[:term])}/i =~ x }
     render json: @trans_array
   end

但是,当我的方法运行查询时它会起作用,但是当我到达行

render json: @trans_array

我收到错误

NoMethodError - undefined method `id' for #<String:0x007fa1af182cb8>:

如何解决这个问题,只显示字符串中单词的一个实例。字符串没有id。只有数组中的字符串。

P.S&GT;这是rails_jquery_autocomplete

的自定义方法

- 编辑 -

controller.rb

class Tenants::TransactionsController < ApplicationController
    before_action :authenticate_user!
    autocomplete :transaction, :trans_names, limit: 5, full: true

   def get_autocomplete_items(params)
      @transaction = current_tenant.user
      @trans_array = @transaction.trans_names.find_all { |x| /#{Regexp.escape(params[:term])}/i =~ x }
      render json: @trans_array
   end
end

当控制器中的这个方法运行时,它会得到只有与用户输入字匹配的行的数组但是它不输出我得到关于字符串“id”的错误

这是错误

    Started GET "/users/transactions/autocomplete_transaction_trans_names?term=uber" for 127.0.0.1 at 2016-07-18 11:06:20 -0500
Processing by Tenants::TransactionsController#autocomplete_transaction_trans_names as JSON
  Parameters: {"term"=>"uber"}
D, [2016-07-18T11:06:20.485530 #27984] DEBUG -- : MONGODB | localhost:27017 | true_numbers_development.find | STARTED | {"find"=>"tenants", "filter"=>{"deleted_at"=>nil, "_id"=>BSON::ObjectId('577ef257d2916212017af892')}, "limit"=>-1}
D, [2016-07-18T11:06:20.486304 #27984] DEBUG -- : MONGODB | localhost:27017 | true_numbers_development.find | SUCCEEDED | 0.000669s
D, [2016-07-18T11:06:20.487448 #27984] DEBUG -- : MONGODB | localhost:27017 | true_numbers_development.count | STARTED | {"count"=>"reportapprovals", "query"=>{"tenant_id"=>BSON::ObjectId('577ef257d2916212017af892')}}
D, [2016-07-18T11:06:20.488221 #27984] DEBUG -- : MONGODB | localhost:27017 | true_numbers_development.count | SUCCEEDED | 0.00067s
D, [2016-07-18T11:06:20.489481 #27984] DEBUG -- : MONGODB | localhost:27017 | true_numbers_development.find | STARTED | {"find"=>"transactions", "filter"=>{"deleted_at"=>nil, "tenant_id"=>BSON::ObjectId('577ef257d2916212017af892')}, "limit"=>-1}
D, [2016-07-18T11:06:20.600603 #27984] DEBUG -- : MONGODB | localhost:27017 | true_numbers_development.find | SUCCEEDED | 0.110952s
Completed 500 Internal Server Error in 120ms

NoMethodError - undefined method `id' for #<String:0x007fa1af1c2570>:
  rails3-jquery-autocomplete (1.0.15) lib/rails3-jquery-autocomplete/autocomplete.rb:101:in `block in json_for_autocomplete'
  rails3-jquery-autocomplete (1.0.15) lib/rails3-jquery-autocomplete/autocomplete.rb:100:in `json_for_autocomplete'
  rails3-jquery-autocomplete (1.0.15) lib/rails3-jquery-autocomplete/autocomplete.rb:75:in `block in autocomplete'
  actionpack (4.0.10) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.0.10) lib/abstract_controller/base.rb:189:in `process_action'
  actionpack (4.0.10) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.0.10) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
  activesupport (4.0.10) lib/active_support/callbacks.rb:433:in `_run__2294321111111650643__process_action__callbacks'
  activesupport (4.0.10) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.10) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (4.0.10) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.0.10) lib/active_support/notifications.rb:159:in `block in instrument'
  activesupport (4.0.10) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.0.10) lib/active_support/notifications.rb:159:in `instrument'
  actionpack (4.0.10) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.0.10) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  actionpack (4.0.10) lib/abstract_controller/base.rb:136:in `process'
  actionpack (4.0.10) lib/abstract_controller/rendering.rb:44:in `process'
  actionpack (4.0.10) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.0.10) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.0.10) lib/action_controller/metal.rb:231:in `block in action'
  actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:82:in `dispatch'
  actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:50:in `call'
  actionpack (4.0.10) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.0.10) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.0.10) lib/action_dispatch/routing/route_set.rb:676:in `call'
  warden (1.2.6) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.6) lib/warden/manager.rb:34:in `call'
  client_side_validations (4.2.4) lib/client_side_validations/middleware.rb:15:in `call'
  rack (1.5.5) lib/rack/etag.rb:23:in `call'
  rack (1.5.5) lib/rack/conditionalget.rb:25:in `call'
  rack (1.5.5) lib/rack/head.rb:11:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/flash.rb:241:in `call'
  rack (1.5.5) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.5.5) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/cookies.rb:486:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.0.10) lib/active_support/callbacks.rb:373:in `_run__3629189788356106492__call__callbacks'
  activesupport (4.0.10) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.10) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/reloader.rb:64:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.0.10) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.0.10) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.0.10) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.0.10) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.0.10) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.0.10) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.5) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.5) lib/rack/runtime.rb:17:in `call'
  activesupport (4.0.10) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
  rack (1.5.5) lib/rack/lock.rb:17:in `call'
  actionpack (4.0.10) lib/action_dispatch/middleware/static.rb:64:in `call'
  rack (1.5.5) lib/rack/sendfile.rb:112:in `call'
  railties (4.0.10) lib/rails/engine.rb:511:in `call'
  railties (4.0.10) lib/rails/application.rb:97:in `call'
  rack (1.5.5) lib/rack/lock.rb:17:in `call'
  rack (1.5.5) lib/rack/content_length.rb:14:in `call'
  rack (1.5.5) lib/rack/handler/webrick.rb:60:in `service'
  /Users/SupremeA/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
  /Users/SupremeA/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run'
  /Users/SupremeA/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'

我可以将我的返回数组更改为Ruby对象,它会像这样返回......

[{"id"=>"8j6OrrEj5EUAqd6qLyM5f4p0xN3DjduYebMJ3",
 "date"=>"2016-07-06", "amount"=>21.41, 
 "name"=>"Debit Card Purchase 07/01 12:13p #4137 UBER US JUL01 YO3SW CA 16184"}, 
 {"id"=>"RkwMDDrkdruO51L5ZPEyCPyzYqVmaeT9ExN4q", "date"=>"2016-07-06", 
  "amount"=>19.18, "name"=>"Debit Card Purchase 07/01 11:07p #4137 UBER US JUL01 HVRD2 CA 16186"}, 
  {"id"=>"QKdMLLjK0jFwZn6ZyM7mC8LZy4VnvOT9BYXzz", "date"=>"2016-07-06",
   "amount"=>16.19, "name"=>"Debit Card Purchase 07/01 03:17p #4137 UBER US JUL01 LIORT CA 16184"}]

但是当我将方法改为

   def get_autocomplete_items(params)
     @transaction = current_tenant.transaction
     @trans_array = @transaction.transactions.find_all { |x| /#{Regexp.escape(params[:term])}/i =~ x[:name] }
     render json: @trans_array.map { |trans| trans[:name] }.uniq
   end

我仍然收到错误

NoMethodError - undefined method `id' for "[\"Amazon\",\"Mama Maria's Pizzeria\"]":String:

1 个答案:

答案 0 :(得分:1)

非常脏的解决方案并没有经过测试,只是因为你问:

class ProxyAutoComplete
    def initialize(options)
       @id = option.delete(:id)
       options.each do |method_name,value|
         self.define_singleton_method(method_name) { value } 
       end
    end
    def id
      @id || __id__
    end
end

然后在创建trans_names数组时,您可以这样做:

trans_names = ["UBER US JUL01 YO3SW CA 16184", 
           "UBER US JUL01 HVRD2 CA 16186", 
           "UBER US JUL01 LIORT CA 16184", 
           "UBER US JUN26 UCF2Z CA 16180", 
           "UBER US JUN27 EZOF5 CA 16180", 
           "UBER US JUN25 BM3LO CA 16179",  
           "UBER US JUN23 5RNBI CA 16177"]
trans_names.map! {|name| ProxyAutoComplete.new({trans_name: name}) } 

然后,您可以看到此对象会根据需要响应trans_nameid

trans_names.each do |n|
  puts "ID: #{n.id} Name: #{n.trans_name}"
end
#ID: 23039892 Name: UBER US JUL01 YO3SW CA 16184
#ID: 23039832 Name: UBER US JUL01 HVRD2 CA 16186
#ID: 23039760 Name: UBER US JUL01 LIORT CA 16184
#ID: 23039700 Name: UBER US JUN26 UCF2Z CA 16180
#ID: 23039640 Name: UBER US JUN27 EZOF5 CA 16180
#ID: 23039568 Name: UBER US JUN25 BM3LO CA 16179
#ID: 23039508 Name: UBER US JUN23 5RNBI CA 16177

这也需要你改变它

class Tenants::TransactionsController < ApplicationController
  #...
  autocomplete :transaction, :trans_name, limit: 5, full: true #second argument must match an option passed to ProxyAutoComplete::new
  #...
end

所有这一切都是假设拥有数据库ID的概念,允许您传递自己的或仅使用内部ID。它还创建了一种方法,可以在您选择的任何方法名称下将值从对象中取回。此方法名称将与作为第二个参数

传递给自动完成方法的方法名称相同

我绝不赞同这个概念,但它应该适用于这个功能(在rails3-jquery-autocomplete宝石的那个部分不应该失败的程度)