Skip to content

Instantly share code, notes, and snippets.

Last active August 29, 2015 13:56
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
The idea here is to give you a simple method that can define your ivar for you, protecting against `nil` proactively, and record the location where the ivar was defined. Best part is, if someone looks for where `#expose` is defined, they'll be happy to find out it's not in a gem. Easy to modify/understand.
# Instead of ditching ivars, just make them easier to discover:
class ApplicationController < ActionController::Base
# Expose an object as an ivar to your views. Explodes if you try to assign nil.
# Use:
# admin = Admin.find_by(email: "admin@test.zz")
# expose(admin) # Defines @admin, because admin.class is Admin
# expose(admin, as: "@user") # Overrides default ivar name
# expose(admin, permit_nil: true) # Does *not* blow up if admin is nil
def expose(object, as: "@#{}", permit_nil: false)
if instance_variable_defined?(as)
raise "Instance variable #{as} already defined!"
if object.nil? && permit_nil
raise "Tried to expose #{as} as nil!"
unless Rails.env.production?
exposed_variables[as] = object, source: caller_locations[1])
instance_variable_set as, object
def exposed_variables
# Add the underscores before and after to indicate that this variable is srs bsns.
@__exposed_variables__ ||= {}
def source_for_ivar(ivar)
exposed_variables.find { |k,v| v.object == ivar }.try(:source)
# Usage
class OrdersController < ApplicationController
def show
order = Order.find(params[:id])
expose order
# When you want to override the name:
class OrdersController < ApplicationController
def show
order = PaypalOrder.find(params[:id])
expose order, as: "@order"
# Now, your view can go back to using ivars, knowing that @order will never be nil,
# and that if you ever need to know where it came from, you can find it.
# app/views/orders/show.html.erb
# <dl>
# <dt>Order Number</dt>
# <dt><%= %></dt>
# </dl>
Copy link

expose(self) is probably a bad practice.

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