# Config.cache\_classes breaks reflect\_on\_assocation?

**URL:** <https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805>\
**Category:** Rails\
**Created:** [February 19, 2009, 9:51pm UTC](https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805 "2009-02-19T21:51:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dino\_d](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b5ac83/32.png) [@dino\_d](https://www.ruby-forum.com/u/dino_d)\
**Post date:** [February 19, 2009, 9:51pm UTC](https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805/1 "2009-02-19T21:51:26Z")

</div>

Hi - I have a model with a user-specific has\_one relationship,  
meaning, my model, Story, has one Vote, but only on a per-user basis.  
So, I addressed this issue by adding a has\_one relationship:

has\_one :current\_user\_vote, :class\_name =\> ‘Vote’, :conditions =\>  
“user\_id = #{Story.current\_user ? Story.current\_user.id : -1}”

And, I added a cattr\_accessor, current\_user (so now the model Story  
has a current user).

And, when the user logs in (or gets logged in by cookie), the method  
set\_current\_user gets called automatically, which looks like this:

def self.set\_current\_user user  
if user  
holder = user.id  
else  
holder = -1  
end  
reflect\_on\_association(:current\_user\_vote).options[:conditions] =  
“votes.user\_id = #{holder}”  
self.current\_user = user  
end

This works fine, unless I enable config.cache\_classes, then, the first  
user who accesses the site after the server is restarted gets his id  
set to current\_user, and everyone else afterward gets the first guy’s  
user\_id set in the association.

So, is there a way to disable only model caching, and cache everything  
else? Or, is this a bug?

Thanks for any help,  
Dino

---

<div class="post-metadata">

**Author:** ![dino\_d](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b5ac83/32.png) [@dino\_d](https://www.ruby-forum.com/u/dino_d)\
**Post date:** [February 20, 2009, 12:03am UTC](https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805/2 "2009-02-20T00:03:40Z")

</div>

On 19 Feb 2009, at 20:50, dino d. wrote:

> This works fine, unless I enable config.cache\_classes, then, the first  
> user who accesses the site after the server is restarted gets his id  
> set to current\_user, and everyone else afterward gets the first guy’s  
> user\_id set in the association.
> 
> So, is there a way to disable only model caching, and cache everything  
> else? Or, is this a bug?

This isn’t a bug - you’re relying on something you should be relying  
on. The reflection builds the sql statement it needs to load the  
association but caches that sql thereafter.  
I don’t think there’s a way round this without changing the way you’re  
doing things.

Fred

---

<div class="post-metadata">

**Author:** ![dino\_d](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b5ac83/32.png) [@dino\_d](https://www.ruby-forum.com/u/dino_d)\
**Post date:** [February 20, 2009, 1:10am UTC](https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805/3 "2009-02-20T01:10:24Z")

</div>

thanks fred (i knew you would be the guy to answer this). so, it  
sounds like you cannot ‘refresh’ a cached model, and once it’s cached,  
you can’t modify it’s cattr (is this right?) . hmm… do you have a  
suggestion for a workaround? I basically have users, stories, and  
votes. users vote on stories. so, i want load all stories and their  
associated votes for a particular user. this was the only way i could  
think of to make a 3 way join.

in the main view of my app, i need to show a batch of stories, with  
all the votes for each story, and the current user’s vote for that  
story, and i want to do it with a single query. adding a current user  
to the model and the reflect\_on does this, and i can’t think of any  
other way.

does class caching dramatically improve performance?

without class caching, am i correct to assume that each session has  
it’s own model object?

thanks again,  
dino

On Feb 19, 6:02 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![dino\_d](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b5ac83/32.png) [@dino\_d](https://www.ruby-forum.com/u/dino_d)\
**Post date:** [February 20, 2009, 2:32am UTC](https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805/4 "2009-02-20T02:32:16Z")

</div>

dino d. wrote:

> This works fine, unless I enable config.cache\_classes, then, the first  
> user who accesses the site after the server is restarted gets his id  
> set to current\_user, and everyone else afterward gets the first guy’s  
> user\_id set in the association.

Yes, this trick stopped working in 2.2 because the reflection  
now caches its conditions SQL.

One workaround is

reflection = reflect\_on\_association(:current\_user\_vote)  
reflection.options[:conditions] = “votes.user\_id = #{holder}”  
reflection.instance\_eval { @sanitized\_conditions = nil }

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)

---

<div class="post-metadata">

**Author:** ![dino\_d](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b5ac83/32.png) [@dino\_d](https://www.ruby-forum.com/u/dino_d)\
**Post date:** [February 20, 2009, 10:39am UTC](https://www.ruby-forum.com/t/config-cache-classes-breaks-reflect-on-assocation/160805/5 "2009-02-20T10:39:52Z")

</div>

On 20 Feb 2009, at 00:09, dino d. wrote:

> all the votes for each story, and the current user’s vote for that  
> story, and i want to do it with a single query.

> adding a current user  
> to the model and the reflect\_on does this, and i can’t think of any  
> other way.  
> It’s not nice but you could have an interpolated condition ie

has\_one :blah, :conditions =\> ‘user\_id = #{Story.current\_user ?  
Story.current\_user.id : -1}’

(note the single quotes there).

I think you’d be better off with something that didn’t involve a class  
level variable like this.

something not far removed from

Story.find :all, :include =\> :votes, :conditions =\> [“votes.id IS NULL  
OR votes.user\_id = ?”, foo]

would do the trick (this is a bit messy in that story.votes will now  
return only votes matching the user)

> does class caching dramatically improve performance?

Yes. It’s pretty much the biggest thing (along with caching in the  
sense of fragment caching etc.) that separates development from  
production performance wise.

Fred
