0

I've moved an application to using ActiveResource and I'm finding that I need to rethink the way I've taught myself to do some things, and I'm searching for the best way to go about this.

For example, I need to keep a query handy say @current_account which I've done as

@current_account ||= Account.where(etc etc)

in an applicationcontroller.rb for a certain scope. This isn't all that useful with AR, because the call to the API is made each time. I'd like to minimize calls to the api (especially where I have other more expensive calls I don't want run on every query, I want to run them once and keep them handy)

So, what is the Rails way? I have to keep a variable with an AR call to an API handy from the ApplicationController in a certain scope, across several other controllers without having to write it out each time (or call the API each time, or put it in a user accesible session because it isn't exactly text/strings, it is objects I need to use).

I'm curious about how others do this, if I should or should not be doing this, what is the right DRY way, etc. So this is somewhat open-ended.

Any input appreciated.

blueblank
  • 4,724
  • 9
  • 48
  • 73
  • Stop asking duplicate questions: http://stackoverflow.com/questions/8370514/activeresource-caching – sethvargo Dec 05 '11 at 21:48
  • This was meant to have a wider scope within the context of Rails application programming, so no. Take some time to read instead of shallow scanning. – blueblank Dec 10 '11 at 14:30

1 Answers1

1

It's best to create a module for this kind of behavior:

module CustomAuth
  def self.included(controller)
    controller.send :helper_method, :current_account, :logged_in?
  end

  def current_account
    # note the Rails.cache.fetch. First time, it will
    # make a query, but it caches the result and not
    # run the query a second time.
    @current_account ||= Rails.cache.fetch(session[:account_id], Account.where(...))
  end

  def logged_in?
    !current_account.nil?
  end
end

Then, make sure that Rails loads up this file (I put mine in ./lib/custom_auth.rb), so add that to the config.autoload_paths in ./config/application.rb:

# ./config/application.rb
...
config.autoload_path += %W(#{config.root}/lib)
...

Import the CustomAuth module into your application_controller.rb:

class ApplicationController < ActionController::Base
  include CustomAuth
  protect_from_forgery

  ...
end

Finally, Crucial: Restart your server

NOTE: You can add additional methods to the custom_auth.rb. If you restart the server, they will be available. These methods are also available in the view, so you can call current_account.name right inside a view.

sethvargo
  • 26,739
  • 10
  • 86
  • 156
  • This is the "DRYest" way that I know of. You have all your authentication namespaced in a single module. You aren't cluttering up `application_controller.rb` with authentication logic, etc. – sethvargo Dec 05 '11 at 20:15