Let's assume that in the example you gave rqst
is returning an empty hash {}
.
When you set selected_unit_req
it is set to an empty hash:
selected_unit_req = rqst.select { |m| select_keys.include?(m) }
=> {}
When you subsequently call selected_unit_req["author"]
the hash is checked for a key named author
, and this returns nil
:
selected_unit_req["author"]
=> nil
So running the full call selected_unit_req["author"]["username"]
can be seen to be equivalent to the following:
nil["username"]
NoMethodError: undefined method `[]' for nil:NilClass
That's why the error is being raised; you expect selected_unit_req["author"]
to return a hash with a key username
but it is instead returning nil
.
Ensure that selected_unit_req
has the hash keys and values that you expect first.
Update
In the comments below you asked how to verify it has the keys you require. The answer to that depends on a few things, like what behavior you want to see in the event it doesn't have it and the version of Ruby you're using.
I'm going to assume that it's okay to skip rqst
if it doesn't have the keys and that you're using a modern version of Ruby (>= 2.3.0).
Here's one way to do it using the dig
method for the Hash class:
request.each do |rqst|
next unless rqst.dig('author', 'username') && rqst.dig('author', 'name')
user = Etl::Models::User.where(username: rqst['author']['username'] )
user.merge!({ author_name: rqst['author']['name'] })
end
What we're doing is calling next
if rqst
does not have the key author
with a sub-key named username
and another sub-key named name
. This works because dig
will return nil
if the hash does not have those keys in it.
Let's pretend for a moment that rqst == {}
. How that line would be interpreted is:
next unless nil && nil
Since nil
is falsy in Ruby, it ends up calling next
to skip over the current rqst
value and move on to the next one in the iteration.
I've also removed selected_unit_req
because it's unnecessarily repetitive; since you already know exactly what keys/values you want out of rqst
there is no need to create a new hash with just those values; instead, you can just extract those values and use them directly where needed.