ruby on rails - Why is counter_cache column not increasing when << an association? -
given have following models:
class location < active::record has_many :storables, foreign_key: :bin_id # ... end class storable < active::record belongs_to :bin, class_name: :location, counter_cache: true # ... end
when run following spec, counter_cache
doesn't increment correctly. method #1
, #2
work expected, not #3
. gives?
describe "location storables" specify "adding storable increments counter cache" l = location.create l.storables_count.should == 0 #=> passes # method 1 s = storable.create(bin: l) l.reload l.storables_count.should == 1 #=> passes # method 2 l.storables.create l.reload l.storables_count.should == 2 #=> passes # method 3 l.storables << storable.create l.reload l.storables_count.should == 3 #=> fails, got 2 not 3 end end
i'm confused counter_cache half working. can't spot configuration problem either.
using rails 3.2.12 on project.
update
upgrading rails 4 didn't help. also, if change method #3 following, test passes:
# method 3 l.storables << storable.create puts "proxy : #{l.storables.count}" #=> 3 puts "relation : #{storable.count}" #=> 3 puts "cache : #{l.storables_count}" #=> 2 location.reset_counters(l.id, :storables) # corrects cache l.reload l.storables_count.should == 3 #=> passes
why isn't happening automatically?
for 1 thing, don't think it's appropriate write l.storables << storable.create
.
by writing this, 2 things happens:
storable.create
creates new storable objectlocation_id
nill.storables <<
updates object created, sets location_idl.id
, , somehow forgets update counter cache.
it might activerecord's fault, since should have been smarter, you've executed 2 sql(insert storable & update storable set location_id = something) insert new storable record. anyway it's bad idea, , if have foreign key constraint on location_id, first insert fail.
so use l.storables << storable.new
instead
ps: l.storables << storable.create
, since return value of storable.create
not new record, it's bit hard l
decide do. in cases, needs increment own counter cache, in other cases, needs increment own counter cache , decrement else's counter cache, or might need nothing.
Comments
Post a Comment