module Puffer
module Extensions
# Extends rails mapper to provide resources nesting tree structure with
# request params. Route defaults contains :puffer key with node
# index in resources tree nodes array. See Puffer::Resource::Tree
#
# Resource tree depends on routes resources nesting.
#
# ex:
#
# namespace :admin do
# resources :users do
# resource :profile
# resources :articles
# end
# resources :orders
# end
#
# will produce:
#
# [
# {:scope => 'admin', :current => :users, :children => [:profile, :articles], :ancestors => []},
# {:scope => 'admin', :current => :profile, :children => [], :ancestors => [:users]},
# {:scope => 'admin', :current => :articles, :children => [], :ancestors => [:users]},
# {:scope => 'admin', :current => :orders, :children => [], :ancestors => []},
# ]
#
# a complete tree structure with nodes array to acces with node index
# (Puffer::Resource::Tree#to_struct).
#
# Also this mapper extension adds come aaditional routes for every pufer
# controller and namespace.
module Mapper
extend ActiveSupport::Concern
included do
alias_method_chain :namespace, :puffer
alias_method_chain :resource_scope, :puffer
end
module InstanceMethods
def namespace_with_puffer path, options = {}
defaults :puffer_scope => path.to_sym do
namespace_without_puffer path, options do
yield
if ::Rails.application.routes.resources_tree.any? {|node| node.scope == @scope[:module].to_sym}
old, @scope[:module] = @scope[:module], 'admin'
root :to => 'dashboard#index'
@scope[:module] = old
end
end
end
end
def resource_scope_with_puffer resource, &block
controller = "#{[@scope[:module], resource.controller].compact.join("/")}_controller".camelize.constantize rescue nil
if controller && controller.puffer?
singular = resource.is_a? ActionDispatch::Routing::Mapper::Resources::SingletonResource
name = (singular ? resource.singular : resource.plural).to_sym
resource_node = ::Rails.application.routes.resources_tree.append_node swallow_nil{@scope[:defaults][:puffer]},
:name => name, :scope => @scope[:module].to_sym, :controller => controller, :singular => singular
defaults :puffer => resource_node do
resource_scope_without_puffer resource do
block.call if block
member do
controller._members.each do |action|
send *action.route
end
end
collection do
controller._collections.each do |action|
send *action.route
end
get '/event/:fieldset/:field/:event(/:identifer)', :action => :event, :as => :event
end
end
end
else
resource_scope_without_puffer resource, &block
end
end
end
end
module RouteSet
extend ActiveSupport::Concern
included do
alias_method_chain :clear!, :puffer
attr_writer :resources_tree
def resources_tree
@resources_tree ||= Puffer::Resource::Tree.new
end
end
module InstanceMethods
def clear_with_puffer!
@resources_tree = nil
clear_without_puffer!
end
end
end
end
end
ActionDispatch::Routing::RouteSet.send :include, Puffer::Extensions::RouteSet
ActionDispatch::Routing::Mapper.send :include, Puffer::Extensions::Mapper