Blankman
Blankman

Reputation: 267020

adding a method to application_controller so it is visible to all controllers and views

I want to create a method that will be available in all controllers, and views.

This method actually makes a db call to get data back, so since it won't be used all the time I want it be be lazily loaded.

class ApplicationController < ActionController::Base


  def some_method
    @object = customdb.call_method(....)
  end

end

To make it lazily loaded do I just do?

@object ||= ....

And how do I propagate this to all controllers and view pages?

Upvotes: 2

Views: 1222

Answers (4)

Mori
Mori

Reputation: 27779

Use helper_method in ApplicationController to make some_method available in any controller or view:

class ApplicationController < ActionController::Base
  helper_method :some_method

  def some_method
    @object ||= customdb.call_method(....)
  end
end

The ||= does per request caching, not lazy loading. Lazy loading is the deferred initialization pattern.

Big scopes and controller methods in views are code smells. Best to minimize object scope and view logic.

Upvotes: 5

Harish Shetty
Harish Shetty

Reputation: 64363

If you want the result to be accessible across accross requests, you have to store the results in a class variable:

class ApplicationController < ActionController::Base
  helper_method :city_list

  def city_list
    @@city_list =|| City.order(:name)
  end
end

The result is lazy loaded and cached. PS: The variable @@city_list is a class variable.

Upvotes: 1

apneadiving
apneadiving

Reputation: 115521

You should use a before_filter

class ApplicationController < ActionController::Base

  before_filter :some_method

  def some_method
    @object = customdb.call_method(....)
  end

end

It will be triggered in all your controllers.

Note that you can skip this before filter using skip_before_filter :some_method wherever you want. You can even prevent only some actions to be preceded by this filter.

Because this will be triggered before all decided controller actions, you won't need your line:

@object ||= ....

Since @object will be instantiated.

Upvotes: 0

Jits
Jits

Reputation: 9728

You could use the memoize feature provided by ActiveSupport

http://api.rubyonrails.org/classes/ActiveSupport/Memoizable.html

http://ryandaigle.com/articles/2008/7/16/what-s-new-in-edge-rails-memoization

So possibly something like:

class ApplicationController < ActionController::Base

  def some_method
    @object = customdb.call_method(....)
  end

  memoize :some_method

end

Upvotes: 1

Related Questions