Ad

How To Use Rails Caches_action With Layout:false And Dynamically Change Meta Tags?

- 1 answer

I am stuck at what I think is a very simple/common usecase in a Rails web application. I want to use "caches_action, layout:false" and display, from the layout, dynamic tags that will be set by the action (either from the view or the controller).

I could not find any standard rails way to do this as content_for does not work with caches_action, instance variables are not cached (?), and the metatags helper gems that I have tried (metamagic and meta-tags) do not support this usecase.

Is there any way to do this ?

Example

I am using caches_action, layout:false on a SandboxController#show method

#app/controllers/sandbox_controller.rb
class SandboxController < ApplicationController

  caches_action :show, layout: false, expires_in: 1.minute

  def show
    @meta_title = "Best page ever"
    do_some_expensive_operation
  end

end

The view

#app/views/sandbox/show.html.erb
We are in show action.

The layout

#app/views/layouts/application.html.erb
<title><%= @meta_title %></title>
Debug: <%= @meta_title %> <br/>
<%= yield %>

Thanks !

Ad

Answer

I found a way to make it work, it's not as pretty as I would like it to be but it helps using caches_action and setting HTML meta tags from the view.

Also, for the record, it seems that this was forgotten and buried deep down in the pipeline, as I did not find any recent mentions of this problem, only that caches_action and content_for together are not expected to work.

Solution: I simply add a before_action to set the meta tags by using as less computation as possible.

#app/controllers/sandbox_controller.rb
class SandboxController < ApplicationController

  caches_action :show, layout: false, expires_in: 1.minute
  before_action :seo_show, only: :show

  def seo_show
    @meta_title = "Best page ever"
  end

  def show
    do_some_expensive_operation
  end

end

It's worth noting that it can be used in combination with metamagic gem too.

Layout:

#app/views/layouts/application.html.erb
<%= default_meta_tags && metamagic %>
<%= yield %>

And helper:

#app/helpers/application_helper.rb
module ApplicationHelper

  def default_meta_tags
    meta title: @meta_title || "Default meta-title of my website"
  end
end

Hope this helps someone out there !

Ad
source: stackoverflow.com
Ad