Don S. wrote:
Don S. wrote:
OK, I was able to resolve this by using reload in my action like this:
def dashboard
user = session[:rbac_user]
@pollers = user.pollers.reload
end
Without the reload, Rails was not fetching the data from the db after
the first rendering. It was just re-rendering the stale data. I’m sure
that neither the action nor the view was being cached because I added a
@now = Time.now in the action and rendered it in the view and it worked
perfectly. But my @pollers collection was not being updated.
The Pick Axe book says (page 220 under the Reloading Data section) “In
practice, reload() is rarely used outside the context of unit tests.”
Any ideas why it would be needed here? Is it simply because this
dataset is being updated outside the application? If so, is this the
best workaround?
Thanks!
Don S. wrote:
Don S. wrote:
OK, I was able to resolve this by using reload in my action like this:
def dashboard
user = session[:rbac_user]
@pollers = user.pollers.reload
end
Without the reload, Rails was not fetching the data from the db after
the first rendering. It was just re-rendering the stale data. I’m sure
that neither the action nor the view was being cached because I added a
@now = Time.now in the action and rendered it in the view and it worked
perfectly. But my @pollers collection was not being updated
Any ideas why it would be needed here? Is it simply because this
dataset is being updated outside the application? If so, is this the
best workaround?
Thanks!
The problem isn’t “caching” as defined in your environment files, but
ActiveRecord query caching so it doesn’t have to run a query it already
knows the answer to. Most of the time an object is only alive for a
single page load, and then recreated form the DB for subsequent page
loads.
user = User.find(1) # SELECT * FROM users WHERE id = 1
user.pollers # SELECT * pollers WHERE user_id = 1
user.pollers # No query
This is standard ActiveRecord behavior, regardless of environment
setting.
Your problem is that youare caching the entire ActiveRecord object in
the session. This gives your object an unintentionally extended life
span. This is precisely the problem with storing the entire object in
the session. AR objects in the session can become stale quickly.
ActiveRecord was designed objects existing briefly, not for extended
periods. But just in case, the reload method is provided to clear out
the old data and get new stuff.
The more common solution is to simply store the user id in the session
rather the user object itself. Then you load the user from the DB on
each page load. This is ESPECIALLY important if you are updating the DB
from outside the rails app itself.
You can reinflate it a few ways. The simplest is to prepare an instance
variable with the user object before every request.
application.rb
before_filter :get_user
def get_user
@user = User.find_by_id(session[:user_id])
end
controller
def dashboard
@pollers = @user.pollers
end