El-Cortez El-Cortez - 2 months ago 19
Ruby Question

Ruby Inject keeps returning NilClass

I'm running a simple SQL query to return a hash.
Although I can effortlessly do it with a .each method, I was hoping I could also do it with the .inject({}) method, but this method returns nil two third of the time.

Can anyone explain what I'm doing wrong?

This is the .each method that works fine

def self.availabilities(days=10)
hash = {}
where(
'date >= ? AND date <= ?',
Date.today, Date.today + days
)
.each do |availability|
p availability
if hash[availability.checker.display_name]
hash[availability.checker.display_name] << availability.date
else
hash[availability.checker.display_name] = [availability.date]
end
end
hash
end


It returns a hash as expected

CheckerAvailability.availabilities(12)).to eql({
'Clint Eastwood' => [Date.today, Date.today + 1.day],
'Bob Morane' => [Date.today + 11.days]
}


This is the inject method

.inject({}) do |hash,elmt|
p "hash ==> #{hash}"
puts '------------------'
if hash[elmt.checker.display_name]
hash[elmt.checker.display_name] << elmt.date
hash
else
hash[elmt.checker.display_name] = elmt.date
hash
end
end


The puts return

"hash ==> {}"
------------------
"hash ==> "
------------------
"hash ==> "
------------------


And if I try to iterate over it, of course it doesn't work.

Thanks anyone for your help

Have a great day !

Answer

You abuse inject by producing redundant intermediate objects. Besides that you should handle element as a block parameter, you should use each_with_object instead of inject. Another glitch is that you should create an array when the respective hash element is missing, while you create a string.

.each_with_object({}) do |elem, hash|
  (hash[elmt.checker.display_name] ||= []) << elmt.date
end

Wrong in your code (besides incorrect block params):

hash[elmt.checker.display_name] = elmt.date

should be:

hash[elmt.checker.display_name] = [elmt.date]
Comments