Skip to content

Instantly share code, notes, and snippets.

@Genkilabs
Created July 11, 2018 17:52
Show Gist options
  • Save Genkilabs/131207d245afb3a39f8a7179412fd899 to your computer and use it in GitHub Desktop.
Save Genkilabs/131207d245afb3a39f8a7179412fd899 to your computer and use it in GitHub Desktop.
How to dynamically select rails views for specific model instances (ie. a specific user)
#An overly complex example of dynamically micro-managing which templates are shown..
class ApplicationController < ActionController::Base
# In this example we assume a using Devise so user_signed_in? and current_user are provided.
# Note: the value returned here could very well be a user's uuid if you needed to provide
# one specific different view for a single or small collection of specific users.
# @returns String || nil
def get_custom_view_name
#This doesn't need to be lazy, but it can be.
@custom_view_name ||= begin
if user_signed_in?
current_user.custom_view_name
end
end
end
protected
# This will add a view lookup path based on a User's theme_name attribute, however
# if this theme does not exist thats ok too, we will still look in the conventional directory
def customize_view_templates
custom_view_path = "app/views/custom/#{get_custom_view_name}"
prepend_view_path( custom_view_path )
end
end
# /app/views/widgets/show.html.erb
# The default view we show to most users.
# NOTE: gist.github.com does not allow multiple files with the same name so I changed its extension, however,
# in your application this would have the same name and extension as the custom version.
<h1>I am an everyday widget</h1>
# /app/views/custom/razzledazzle/widgets/show.html.erb
# The custom view we show to users where current_user.custom_view_name == 'razzledazzle'
<h1>Hello <%= current_user.name %>, I am a customized widget just for you (and maybe your friends)</h1>
class WidgetsController < ApplicationController
# Allows us to make custom client views in /app/views/custom/#{custom_view_name}/api/v1/widgets/show
before_action :customize_view_templates, :only => [:show]
end
@Genkilabs
Copy link
Author

Genkilabs commented Jul 11, 2018

The benefit here is that I wanted to avoid doing something like

if current_user.custom_view_name.blank?
  render
else
  render( :template => "app/views/custom/#{current_user. custom_view_name}"/controller/action)
end

Which would need to exist in some form in every action that could be overwritten; and I felt was less maintainable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment