How to fix "undefined method `key?'" in Rails with Grape

2k Views Asked by At

I'm creating an API with Ruby on Rails. I use the gem 'grape' to provide the api to the consumer and 'spyke' to receive data from another api. I manipulate and enrich the data I receive from spyke and then pass it on to grape.
The problem is, that I receive an error: undefined method key?.

I've already checked the data I receive from spyke. The data seems ok (I don't receive an array, I get a Hash). I've printed it with puts result and result.class (result being the data spyke receives).
I've googled the error message undefined method key?. I tried all "solutions" provided by stackoverflow and other resources. None of them worked. I don't even know where the error is originated exactly.

resource :clusters do
  route_param :cluster_id do
    resource :stats do
      params do
        requires :node, type: String, desc: 'Node name.'
      end
      route_param :node do
        get do
          present StatsNode.where(cluster_id: params[:cluster_id], node: params[:node]), with: StatsNodeEntity
        end
      end
    end
  end
end

I don't know if this is important, but when I raise a string raise 'test' before the line present StatsNode.where..., the message {"response_type":"error","response":"asdf"} appears as the response. If I raise the string after the present line, then the initial error message appears.

The exact message reads: {"response_type":"error","response":"undefined method key?' for [\"_nodes\", {\"total\"=\u003e1, \"successful\"=\u003e1, \"failed\"=\u003e0}]:Array"}

I expect, that the api returns a json with the data and not with the error message.
Where is the error message from and how can I fix this problem?

EDIT:
I'm using:
- Ruby 2.5.5
- Rails 5.2.3
- spyke latest
- grape latest
- grape-entity latest

1

There are 1 best solutions below

3
On

Without having seen the code for StatsNode or StatsNodeEntity, I'm going to assume that the following is true:

  • StatsNode is an ActiveRecord (or ActiveRecord-like) model
  • StatsNode.where() returns an enumerable like ActiveRecord::Relation (with Array-like behavior)

Given that, the problem is most likely that your where() call is returning an array-like object when you expect it to return a single hash-like object. You can see that from the error:

{"response_type":"error","response":"undefined method key?' for [\"_nodes\", {\"total\"=\u003e1, \"successful\"=\u003e1, \"failed\"=\u003e0}]:Array"}

It's telling you you're trying to call .key? on an Array object.

The solution is probably to change this call:

StatsNode.where(cluster_id: params[:cluster_id], node: params[:node])

to:

StatsNode.find_by(cluster_id: params[:cluster_id], node: params[:node])