using layouts in Rails assets - ruby-on-rails

I have a lot of html pages on my site that are static, but I serve them dynamically through the typical rails controller & view setup just because I want to use my application.html.erb layout and not have to worry about changing it in multiple places if I just cut and paste it into a static html file I put in my public directory.
I recently upgraded to Rails 3.2 however, and the asset pipeline and its precompiling of assets sounded like a perfect fit for this problem. However, I have not seen any good documentation on how to write a *.html.erb asset, and direct it to use application.html.erb, or any other layout for that matter. can someone post how to do this, or point me to a good resource? Thanks!

Instead of trying to serve the static html partials through the asset pipeline, have you thought about just caching them?
If what your worried about is actually getting the static partial to be rendered then you might want to try the following in your view. The following would be for your nav.
-cache 'main-nav' do
=render :partial => 'layouts/nav'
This way on the first load it would retrieve your partial, and all subsequent loads it would retrieve it from your cache, which if you have redis or memcache set up, should make it blazing fast.

Related

In Ruby on Rails is there a way to put the path of every partial in an HTML comment?

I work on apps that often have thousands of partials and finding what partial is rendering a section of HTML can be tedious and just waste time.
In development mode, it would sometimes be very helpful to turn on a config to have every partial used be prefaced with its path in an HTML comment so I could quickly know how to access and edit it.
Is there a config option for this or a gem that someone has made for this?
This functionality is built-in to recent rails versions for erb templates.
See here for details: https://blog.saeloun.com/2020/05/11/rails-support-annotates-html-output-with-template-file-names.html
That page mentions another option you could try.
Here is a link to the rails pr that introduced the change: https://github.com/rails/rails/pull/38848

Compile Rails application to static site

I want to know if there is a way (or a gem) that can compile me a Rails application into a static web site; I have some files that need to only be compiled once (i.e. they have no dynamic content but they need to be parsed at least once). I can't seem to find any way to do that so I have a feeling that it might not even be possible.
I don't believe there's a way to do that with an entire Rails app. That's more the territory of https://github.com/mojombo/jekyll or https://github.com/imathis/octopress. If it's only a few pages you can use caches_page :page1, :page2, ... in your controllers. That will write the fully-rendered page to public/ so that it can be served directly by Nginx/Apache on subsequent requests.
Edit In Rails 4 you'll need to use the actionpack-page_caching gem.

Rails Cached partial in layout is rendered twice

I am trying to cache a partial which is rendered in a layout. This partial is computationally expensive so I only want to compute it once. It is not controller specific so the usual fragment caching doesn't seem to apply. I decided to use Rails.cache.fetch('menu') for the caching instead. Here is what the contents of the partial look like.
<% Rails.cache.fetch('menu') do %>
Partial code...
<% end %>
But when I do this it renders the partial twice. For some reason it stopped doing this in my development environment so I decided to try and deploy it. I am not so lucky with my production environment. The partial itself generates a menu that includes links to a lot of the records in the site to help improve navigation.
I originally tried putting the cache statement in the layout file but then it was rendering the layout twice.
I recently added a jQuery hack to remove the duplicate html so that it kinda "works" for now, but I would rather get it working properly. I don't want to go to the trouble of installing some complicated caching system such as Redis, that requires me to run another server program. That would be overkill for the task. There must be something in rails that is well suited to caching parts of layouts.
Should I try something completely different or is this a bug in rails? If it is a bug then is there a workaround I can use?
I figured it out. Instead of caching the partial in the view, I created a helper method that returns the rendered partial.
#Returns a menu for the application layout
def menu
Rails.cache.fetch('menu') { render :partial => 'all/menu' }
end
Then all I needed in the layout is this line
<% menu %>
Try clearing your production cache. Chances are you had a logic error that was causing it to render twice. In development, the cache is usually disabled so that's why when you fixed the problem it went away in development. If you have redeployed, the issue is probably gone from the production code as well, but if the cache has not been cleared, it will keep displaying the cached logic error.

How do I serve nested static content on Heroku?

I have a rails application with static content in the public directory (e.g. public/index.html) and additional static content in nested subdirectories (e.g. public/one/two/index.html).
All the static content is served correctly if I run it locally via script/server but when I upload it to Heroku the top-level page loads correctly but the nested content returns a 404.
I've found a number of resources (for example this question) which discuss static content in rails but they all seem to assume a fairly simple structure with a single directory containing all the files.
Is there any way I can fix this?
If you have a very simple web application (with mostly static content, say) then using Sinatra on Heroku is much simpler to set up and prevents this type of problem.
You can serve up static content on Heroku without writing any "code" at all... you just need to tell the "Rack" middleware where the content is (as detailed in this help article):
http://devcenter.heroku.com/articles/static-sites-on-heroku

Rendering an externally modified file in Rails

I've got a cron job parsing a few XML feeds every ten minutes and creating a few partials to include on every page in my Rails project with the render: file method. The problem is that, obviously, they don't refresh until the server restarts.
Anyway, what can I do to force rails to refresh this file every time?
Thanks in advance.
Use instead:
render :inline => File.read(file_name), :layout => true
I think you are misusing render(:file). This is definitely not how it is intended to be used. Rendering a partial is supposed to be used to render a modular piece of erb (or whatever template lang you use) code in multiple places, not a data-load technique. You're using it (it appears) to load dynamically changing data.
I think what you're really trying to do is fragment caching, but without more context, I could be wrong.
For a great walkthrough on fragment caching: http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2
Probably your cron job would run a script/runner script that would create the fragment you're looking to cache.
If I'm off base here, please try to clarify what type of file you're loading and what you're trying to accomplish.
This happens because in production mode Rails cashes all its classes and views/partials. To solve this problem you can render your partials inside fragment caching block and use method expire_fragment when you want to refresh block content. Other way can be switching to the development mode but it will make your application slower.

Resources