caching - How do I force rails to not use a cached result for has_many through relations? -


i have following 3 models (massively simplified):

class < activerecord::base   has_many :bs   has_many :cs, :through => :bs end  class b < activerecord::base   belongs_to :a   has_many :cs end  class c < activerecord::base   belongs_to :b end 

it seems a.cs gets cached first time used (per object) when i'd rather not.

here's console session highlights problem (the fluff has been edited out)

first, way should work

rails console 001 > b = b.create 002 > c = c.new 003 > c.b = b 004 > c.save 005 > = a.create 006 > a.bs << b 007 > a.cs => [#<c id: 1, b_id: 1>] 

this indeed expect. a.cs going nicely through a.bs relation.

and caching infuriations

008 > a2 = a.create 009 > a2.cs => [] 010 > a2.bs << b 011 > a2.cs => [] 

so first call a2.cs (resulting in db query) quite correctly returned no cs. second call, however, shows distinct lack of cs though jolly should there (no db queries occurred).

and test sanity not blame

012 > a.find(a2.id).cs => [#<c id: 1, b_id: 1>] 

again, db query performed both record , associated c's.

so, question: how force rails not use cached result? of course resign myself doing workaround (as shown in console step 12), since result in 2 queries when 1 necessary, i'd rather not.

i did more research issue. while using clear_association_cache convenient enough, adding after every operation invalidated cache did not feel dry. thought rails should able keep track of this. thankfully, there way!

i use example models: (has many b, has many c through b), b (belongs a, has many c), , c (belongs b).

we need use touch: true option belongs_to method. method updates updated_at attribute on parent model, more importantly triggers after_touch callback. callback allows automatically clear association cache instance of whenever related instance of b or c modified, created, or destroyed.

first modify belongs_to method calls b , c, adding touch:true

class b < activerecord::base   belongs_to :a, touch: true   has_many   :cs end  class c < activerecord::base   belongs_to :b, touch: true end 

then add after_touch callback a

class < activerecord::base   has_many :bs   has_many :cs, through: :bs    after_touch :clear_association_cache end 

now can safely hack away, creating sorts of methods modify/create/destroy instances of b , c, , instance of belong automatically have cache date without having remember call clear_association_cache on place.

depending on how use model b, may want add after_touch callback there well.

documentation belongs_to options , activerecord callbacks:

http://api.rubyonrails.org/classes/activerecord/callbacks.html
http://api.rubyonrails.org/classes/activerecord/associations/classmethods.html#method-i-belongs_to

hope helps!


Comments

Popular posts from this blog

assembly - 8086 TASM: Illegal Indexing Mode -

Java, LWJGL, OpenGL 1.1, decoding BufferedImage to Bytebuffer and binding to OpenGL across classes -

javascript - addthis share facebook and google+ url -