Reputation: 3299
I'm attempting to post a random testimonial on each page of a site.
I started off by using an application helper like this:
module ApplicationHelper
def random_testimonial
@random_testimonial = Testimonial.find(:first, :offset => rand(Testimonial.count))
end
end
In my view I can reference the method but it's being called on each reference, which makes sense.
I'd like this to be called once on each page view exposing a Testimonial object I can use within the view.
What should I be looking for to do this?
Upvotes: 20
Views: 27859
Reputation: 2308
While that works, and I have certainly been known to do this, it violates the MVC separation of concerns. View helpers are not supposed to contain controller/model type logic, which this does.
You might consider refactoring this back into the application controller. Helpers are supposed to be for view formatting and stuff, more than as a function (which is what I kept wanting to do when I got started.)
If you got back into your Testimonail model, do could do
def self.random
Testimonial.find(:first, :offset => rand(Testimonial.count))
end
then in your application controller, you could do:
def random_testimonial
@random_testimonial ||= Testimonial.random
end
and call it from a before_filter
This has the advantage of moving the database logic back into the model where it belongs.
Upvotes: 50
Reputation: 15598
If I understand you correctly, you want a method that returns the same object every time it is referenced in one request/response cycle. If this is true, you can achieve it with a minor change to your helper:
def random_testimonial
@random_testimonial ||= Testimonial.find(:first, :offset => rand(Testimonial.count))
end
Notice the "||=" part. That's a Ruby idiom which says: assign a value to @random_testimonial, unless it already has a value.
Hope that answers your question.
Upvotes: 6