I have a web application with a category tree that is published on the home page with about 1200 categories. This category tree is built using acts_as_tree (parent_id etc) which builds a tree in html using <ul> and <li>.
If I publish the tree straight off it works perfectly fine but is really quite slow (~4 secs loading time), which obviously is not good for a home page.
The good thing is that this category tree rarely changes so it can be built upon startup of the server. Thus, what I did was to create an initializer category_tree.rb and put it in the initializers-folder.
I made a global variable $category_tree and “inserted the html” in there sort of like this (this is an oversimplified example):
def create_tree(categories)
ret = '<ul>'
categories.each do |cat|
ret = "<li><a href='" + cat.url + "'>" + cat.name + "</a>"
end
ret = '</ul>'
end
$category_tree = create_tree(Category.all)
and then, in my index-view I simply put:
<%= $category_tree %>
This all WORKS! It loads fast and correct. But, I have some issues that I would like some help with:
-
Using
<a href>will not be very stable in the long run. I would prefer using link_to and the paths but the problem is that my initializer loads before routes.rb it seems. This makes it impossible to call category_path for example. How can I solve this? How can I make the category_tree.rb load AFTER routes.rb is loaded? -
I don’t know if using a global variable like this is very smart. I imagine it would keep my category tree html in the memory all the time, which I assume is not too smart. Is this correct?
What I would prefer is a situation where I create a partial upon startup that contains my html category tree in which I can use routes/paths. A solution that will not need to keep anything in the memory. How can I solve that?
Looks like you should try caching the page after you have rendered it. When changed, invalidate the cache and load it yourself to store a new cached version.
http://guides.rubyonrails.org/caching_with_rails.html