Skip to content

Instantly share code, notes, and snippets.

@cypriss
Created June 13, 2009 11:06
Show Gist options
  • Save cypriss/129198 to your computer and use it in GitHub Desktop.
Save cypriss/129198 to your computer and use it in GitHub Desktop.
Dynos - an alternative to NBB Engines. Namespaced controller methods available in any controller.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# ...
before_filter :update_dyno
def dyno
@@dyno_set ||= DynoSet.new
end
def update_dyno
dyno.update_controller(self)
end
end
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
# NOTE: I prefer dyno.widget_list as opposed to widget_list with a method_missing in ApplicationController -- it is clear where the method is located.
@widgets = dyno.widget_list
@accounts = dyno["accounts"].account_list
end
end
# app/controllers/accounts_controller.rb
class AccountsController < ApplicationController
def index
@widgets = dyno["widgets"].widget_list
@accounts = dyno.account_list
end
end
# app/dynos/home_dyno.rb
class HomeDyno < Dyno
def widget_list
# ...
end
end
# app/dynos/accounts_dyno.rb
class AccountsDyno < Dyno
def account_list
# ...
if params[:sort] == "balance" # NOTE: can use params here, which is defined in controller...
# ...
end
end
end
# lib/dyno.rb
class Dyno
def initialize(parent)
@parent_controller = parent
end
def update_controller(parent)
@parent_controller = parent
end
# If a dyno can't handle the method, send it to the corresponding controller.
def method_missing(method, *args, &proc)
@parent_controller.send(method, *args, &proc)
end
end
class DynoSet
def initialize
@dynos = {}
end
def update_controller(parent)
@parent_controller = parent
@dynos.each_pair do |k, v|
v.update_controller(parent)
end
end
def [](cont_str)
raise Exception, "parent controller not set!" unless @parent_controller
@dynos[cont_str.to_s] ||= "#{cont_str.camelize}Dyno".constantize.new(@parent_controller)
end
# If we ask the dynoset for a method, assume it's on the current controller (based on params). Ask that dyno.
def method_missing(method, *args, &proc)
raise Exception, "parent controller not set!" unless @parent_controller
self[@parent_controller.params[:controller]].send(method, *args, &proc)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment