views:

47

answers:

4

So I have a method and corresponding partial for including a set of random photos in the sidebar of certain areas of our site.

Right now I have a random_photos method in ApplicationController set with a before_filter.

That works in the sense that it makes the contents of the random_photos method available wherever I need it, but it also unnecessarily executes some complex SQL queries when I don't know it too (ie, when I don't need to access those random photos).

So, how can I limit the accessing of the random_photos method to only when I really need it?

+2  A: 

You can add an :if condition to the before_filter call, like so:

class ApplicationController < ActiveController::Base
  before_filter :random_photos, :if => is_it_the_right_time?
vrish88
A: 

You can keep the random_photos method in ApplicationController, and put the before_filters in your other controllers.

class ApplicationController < ActiveController::Base
  ...
  def random_photos
    @photos = Photo.random
  end
end

class OtherController < ApplicationController
  before_filter :random_photos, :only => 'show'
  ...
end
Ben
A: 

Yet another option is to use skip_before_filter. It just depends in how many controllers you want to be different. Use skip_before_filter if there are only a handful of controllers you want to be the exception. Use one of the other suggestions if there are many controllers where you want to bypass the filter.

class ApplicationController < ActiveController::Base
   before_filter :random_photos

   def random_photos
     @photos = Photo.random
   end
end

class OtherController < ApplicationController
  skip_before_filter :random_photos
  ...
end
JosephL
A: 

It depends on how many functions are making use of random_photos...

If a handful then use vrish88's approach but with an after_filter:

class ApplicationController < ActiveController::Base
  after_filter :random_photos, :if => is_it_the_right_time?
  ...
  private

  def is_it_the_right_time?
    return @get_random_photos
  end
end

class SomeController < ApplicationController

  def show
    @get_random_photos = true
    ...
  end
end

If every function in a controller will make use of it then use the skip_before_filter or move the before_filter in the controller and out of the application controller.

Many ways to get it done, and none is more correct then the next. Just try to keep it as simple and transparent as possible so you don't recreate the functionality months down the road because you forgot where all the pieces are located.

Tony Fontenot