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:

  1. storable.create creates new storable object location_id nil

  2. l.storables << updates object created, sets location_id l.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

Popular posts from this blog

javascript - Count length of each class -

What design pattern is this code in Javascript? -

hadoop - Restrict secondarynamenode to be installed and run on any other node in the cluster -