rails: AR 4.2.1 .includes give undefined method `each' for nil:NilClass
I use MSSQL as primary db. It use decimal(19, 0) type for ids. I have 2 models:
class TaskCardImportStatus < ActiveRecord::Base
has_many :poison_records, class: TaskCardImportPoisonRecord
....
end
class TaskCardImportPoisonRecord < ActiveRecord::Base
belongs_to :task_card_import_status
end
when I try to do
rows = InvoiceImportStatus.includes(:poison_records).all
and after that access each elements like:
rows.each do |r|
puts r.id
end
I get exception:
NoMethodError: undefined method `each' for nil:NilClass
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader/association.rb:96:in `block in associated_records_by_owner'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader/association.rb:94:in `each'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader/association.rb:94:in `associated_records_by_owner'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader/collection_association.rb:13:in `preload'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader/association.rb:20:in `run'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader.rb:146:in `block (2 levels) in preloaders_for_one'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader.rb:144:in `each'
from /Users/viktornazarenko/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.1/lib/active_record/associations/preloader.rb:144:in `map'
Looks like problem is here:
records.each do |record, owner_key|
owners_map[owner_key].each do |owner|
records_by_owner[owner] << record
end
end
I made a small debug and found that owners_map do mapping by ids in float point format like this:
{"38.0"=>[#<InvoiceImportStatus id: #<BigDecimal:7fd29a4e4278,'0.38E2',9(18)>, completedAt: ...}
But then try to access it with integer id (owner_key == “38” in this case" )
owners_map[owner_key]
and it will not be found in map ( “38.0” != “38” )
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 20 (6 by maintainers)
@sgrif Helped me out here by letting me know how to coerce the ID out of the table. So by adding
attribute :id, Type::Integer.new
on my model (the one with the float as a primary key), I can now properly useincludes
without hitting the.each
error.YMMV
I’m hitting this error randomly on production, but the cause is a bit obscure. Since I can’t reproduce it locally I added debugging statements and we got an insight on what’s happening, but don’t understand why. We are using Postgres 9.4 and rails 4.2.5.2.
It looks like the associated AR model retrieved from the database has an ID of 0 which causes the
owner_key
to be0
. And, since theowners_keys
has no key with value 0 then we get the exception ofundefined method
each’ for nil:NilClass`.This is the context we logged:
The problem is that
owner_keys
does not contain akey=0
, which is correct since none of the owners are pointing to a company that has the ID=0. Both fields (primary_key and association_key) are integer, so no key conversion is required.It seems that the problem is when
records_for(ids)
is called one of the records comes back with theid=0
even though that value is not in the list ofids
.Any ideas on why does the AR model has an ID of 0?
* Note:* On some other instances the AR model has
all fields
with the valuenil
. So eitherID=0
orall fields = nil
.