If your application needs to know if a user has some calls waiting at each page load, and that information is kept only in the database, then yes, I'd expect that you'd have to query the database for that information at each page load.
As far as DRYness goes, Rails provides a number of mechanisms throughout the MVC stack that ensure that keep things DRY and maintainable:
In the model, you could add a class method to your Call model to encapsulate the logic for the querying awaiting calls. It could be something like:
class Call < ActiveRecord::Base
def self.awaiting_for_user user
self.all(:conditions => ['user_id = ? AND active = true', user])
end
By encapsulating the query in a method like this, you ensure that if the underlying logic to query that information changes, your invocations of that method will not.
Instead of adding this method call to each controller actions (index, show, etc.), you could use the controller before_filter/around_filter/after_filters methods to run this code on sets of controllers/actions.
class ApplicationController
before_filter :load_current_user
before_filter :load_current_users_calls
....
protected
def load_current_user
# You could encapsulate this method in your User model
@user = User.find(session[:user_id])
end
def load_current_users_calls
@calls = Call.awaiting_for_user(@user)
end
Use the before_filter options like :except and :only to pinpoint the use of the filter in particular controller actions. Also, while declaring the actual load_current_users_calls methods in the ApplicationController ensures that each sub-classed controller has that method, you don't have to put the before_filter declaration in ApplicationController -- you could just put it any controller you want to run the before_filter.
And in the view layer, you could make partial to easily display the @calls in your standard layout. You could add something like this to your layout:
<%- if @calls && [email protected]? -%>
<%= render :partial => 'awaiting_calls_display', :locals => {:calls => @class} =%>
<%- end -%>
Or if that doesn't fit in your layout, you could call it from any applicable views.