module Nitro # Scaffolding is one facet of Nitro's Rapid Application # Develpoment (RAD) features. The scaffolder automatically # generates common code for managed object and their # controllers. module Scaffold # Automatically enchant all entities? setting :enchant_all_entities, :default => true, :doc => 'Automatically enchant all entities?' module ClassMethods # 'Enchant' a class (typically a managed class). A # collection of useful methods are magically added to the # class and/or the class instances. # # to_s # to_href # to_link # to_edit_href # to_admin_href # #-- # to_xxx is used instead of xxx in an attempt to avoid # colisions with user defined methods. #++ def enchant *classes for c in classes enchant_class c end end #-- # Actually enchant the given class. Override this method # to customize for your application. The string calculation # code is deliberatly dynamic to work with Ruby's OO # features. #++ def enchant_class klass # to_s if klass.respond_to? :title define_instance_method klass, :to_s, %{ title }, force = true elsif klass.respond_to? :name define_instance_method klass, :to_s, %{ name }, force = true end # to_href # ex: blog/articles/23 define_instance_method klass, :to_href, %{ "\#{self.class.ann.self.controller.mount_path}/\#{self.class.name.underscore.pluralize}/\#{oid}" } # to_link # ex: The article's title define_instance_method klass, :to_link, %{ %|\#{to_s}| } # to_edit_href # ex: admin/articles/edit/23 define_instance_method klass, :to_admin_href, %{ "\#{AdminController.mount_path}/\#{self.class.name.underscore.pluralize}/edit/\#{oid}" } if defined? AdminController # to_admin_href # ex: admin/articles/list define_instance_method klass, :to_admin_href, %{ "\#{AdminController.mount_path}/\#{self.class.name.underscore.pluralize}/list" } # to_admin_href # ex: admin/articles/list define_class_method klass, :to_admin_href, %{ "\#{AdminController.mount_path}/\#{self.name.underscore.pluralize}/list" } end end private #-- # This helper defines an instance method for the # scaffolded class. The method is only defined if the klass # does not already respond to it. #++ def define_instance_method klass, meth, body, force = false unless force or klass.instance_methods.include? meth.to_s klass.module_eval %{ def #{meth} #{body} end } end end #-- # This helper defines an class method for the # scaffolded class. The method is only defined if the klass # does not already respond to it. #++ def define_class_method klass, meth, body unless klass.respond_to? meth.to_s klass.module_eval %{ def self.#{meth} #{body} end } end end end def self.included base base.extend ClassMethods end # Make the Scaffold module also work as a singleton, ie: # # Scaffold.enchant Article, Category extend ClassMethods end end # * George Moschovitis