Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails Layout reading data from Model

I am working on a RoR application and I am working on writing the blog component. I am planning to have a layout file that will display all of the tags from the database on each page within blog component. I know how to create and use a different layout file other than application.html.erb, but what I don't know is how to read the tags list from the database for each action in the various controllers. I would not like to create the appropriate instance variable within each action. What is an appropriate way to approach this?

like image 565
Mark S. Avatar asked Feb 12 '11 21:02

Mark S.


3 Answers

Use a before_filter in your application_controller to create the instance variable:

before_filter :populate_tags

protected

def populate_tags
  @sidebar_tags = Tag.all
end
like image 175
Chris Heald Avatar answered Nov 06 '22 07:11

Chris Heald


I would recommend using a before_filter, but also caching your result in memcached. If you are going to be performing this action on every request it's best to do something like this:

class ApplicationController
  before_filter :fetch_tags

  protected

  def fetch_tags
    @tags = Rails.cache.fetch('tags', :expires_in => 10.minutes) do
      Tag.all
    end
  end
end

This will ensure that your tags are cached for a certain period of time (for example 10 minutes), so that you only have to make this query once every 10 minutes, rather than on each request.

You can then display your tags in your sidebar, for example, if you had a _sidebar partial that is displayed in your layouts, you could do the following.

#_sidebar.html.erb
render @tags
like image 45
Pan Thomakos Avatar answered Nov 06 '22 07:11

Pan Thomakos


Define a private method in the ApplicationController and load it there with a before_filter. Since all controllers inherit from the ApplicationController, it will executed before each action.

Another idea would be loading it via a helper method, but I would prefer the first solution.

like image 1
iGEL Avatar answered Nov 06 '22 08:11

iGEL