require 'glue/inflector' module Nitro # The scaffolder adds default actions to a Controller. #-- # FIXME: handle controller base in generated routes. # FIXME: better handle templates (check if action exists). #++ module Scaffolding def self.append_features(base) # :nodoc: super base.extend(ClassMethods) end module ClassMethods # Enchant the caller with a number of default methods. # Override the automatically generated methods as needed. def scaffold(klass, options = {}) oid = options[:oid] || 'oid' name = options[:name] || Inflector.name(klass.name) list_name = options[:list_name] || Inflector.plural_name(name) options[:nosuffix] ? suffix = nil : suffix = "_#{name}" # Add methods to the scaffolded class. klass.module_eval %{ def to_href "view#{suffix}?oid=\#\{@oid\}" # "view#{suffix}/\#\{@oid\}" end } # Add methods to the service. code = '' if options[:index] code << %{ def index list#{suffix} end } end code << %{ def new#{suffix} @#{name} = #{klass}.new render '/form#{suffix}' end def edit#{suffix} @#{name} = #{klass}[request['oid']] render '/form#{suffix}' end } unless Rendering.template_for_action(self.template_root, "form#{suffix}") code << %{ def form#{suffix} o << %|
| if @#{name}.oid o << %| | end o.build_form(@#{name}) o << %|
| end } end code << %{ # TODO: add pager support here! def list#{suffix} @#{list_name} = #{klass}.all('ORDER BY oid') } unless Rendering.template_for_action(self.template_root, "list#{suffix}") code << %{ o.ul { for item in @#{list_name} o.li(item.to_s) end } } end code << %{ end def view#{suffix} # @#{name} = #{klass}[@context['#{oid}']] @#{name} = #{klass}[@#{oid}] end action :view#{suffix}, :route => \%r\{#{@base}/view#{suffix}/(.*)\}, 'oid' => 1 def save#{suffix} if oid = request['oid'] @#{name} = request.fill(#{klass}[oid]) else @#{name} = request.fill(#{klass}.new) end @#{name}.save redirect 'list#{suffix}' end def del#{suffix} #{klass}.delete(@context['#{oid}']) end alias_method :delete#{suffix}, :del#{suffix} } class_eval(code) end end end end