Module: ActionController::Scaffolding::ClassMethods
- Defined in:
- lib/action_controller/scaffolding.rb
Overview
Scaffolding is a way to quickly put an Active Record class online by providing a series of standardized actions for listing, showing, creating, updating, and destroying objects of the class. These standardized actions come with both controller logic and default templates that through introspection already know which fields to display and which input types to use. Example:
class WeblogController < ActionController::Base
scaffold :entry
end
This tiny piece of code will add all of the following methods to the controller:
class WeblogController < ActionController::Base
def index
list
end
def list
@entries = Entry.find_all
render_scaffold "list"
end
def show
@entry = Entry.find(@params["id"])
render_scaffold
end
def destroy
Entry.find(@params["id"]).destroy
redirect_to :action => "list"
end
def new
@entry = Entry.new
render_scaffold
end
def create
@entry = Entry.new(@params["entry"])
if @entry.save
flash["notice"] = "Entry was succesfully created"
redirect_to :action => "list"
else
render "entry/new"
end
end
def edit
@entry = Entry.find(@params["id"])
render_scaffold
end
def update
@entry = Entry.find(@params["entry"]["id"])
@entry.attributes = @params["entry"]
if @entry.save
flash["notice"] = "Entry was succesfully updated"
redirect_to :action => "show/" + @entry.id.to_s
else
render "entry/edit"
end
end
end
The render_scaffold method will first check to see if you’ve made your own template (like “weblog/show.rhtml” for the show action) and if not, then render the generic template for that action. This gives you the possibility of using the scaffold while you’re building your specific application. Start out with a totally generic setup, then replace one template and one action at a time while relying on the rest of the scaffolded templates and actions.
Instance Method Summary collapse
-
#scaffold(model_id, options = {}) ⇒ Object
Adds a swath of generic CRUD actions to the controller.
Instance Method Details
#scaffold(model_id, options = {}) ⇒ Object
Adds a swath of generic CRUD actions to the controller. The model_id is automatically converted into a class name unless one is specifically provide through options[:class_name]. So scaffold :post would use Post as the class and @post/@posts for the instance variables.
It’s possible to use more than one scaffold in a single controller by specifying options[:suffix] = true. This will make scaffold :post, :suffix => true use method names like list_post, show_post, and create_post instead of just list, show, and post. If suffix is used, then no index method is added.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/action_controller/scaffolding.rb', line 84 def scaffold(model_id, = {}) ([ :class_name, :suffix ], .keys) require "#{model_id.id2name}" rescue logger.warn "Couldn't auto-require #{model_id.id2name}.rb" unless logger.nil? singular_name = model_id.id2name class_name = [:class_name] || Inflector.camelize(singular_name) plural_name = Inflector.pluralize(singular_name) suffix = [:suffix] ? "_#{singular_name}" : "" unless [:suffix] module_eval " def index\n list\n end\n end_eval\n end\n \n module_eval <<-\"end_eval\", __FILE__, __LINE__\n def list\#{suffix}\n @\#{plural_name} = \#{class_name}.find_all\n render\#{suffix}_scaffold \"list\#{suffix}\"\n end\n\n def show\#{suffix}\n @\#{singular_name} = \#{class_name}.find(@params[\"id\"])\n render\#{suffix}_scaffold\n end\n \n def destroy\#{suffix}\n \#{class_name}.find(@params[\"id\"]).destroy\n redirect_to :action => \"list\#{suffix}\"\n end\n \n def new\#{suffix}\n @\#{singular_name} = \#{class_name}.new\n render\#{suffix}_scaffold\n end\n \n def create\#{suffix}\n @\#{singular_name} = \#{class_name}.new(@params[\"\#{singular_name}\"])\n if @\#{singular_name}.save\n flash[\"notice\"] = \"\#{class_name} was succesfully created\"\n redirect_to :action => \"list\#{suffix}\"\n else\n render \"\#{singular_name}/new\#{suffix}\"\n end\n end\n \n def edit\#{suffix}\n @\#{singular_name} = \#{class_name}.find(@params[\"id\"])\n render\#{suffix}_scaffold\n end\n \n def update\#{suffix}\n @\#{singular_name} = \#{class_name}.find(@params[\"\#{singular_name}\"][\"id\"])\n @\#{singular_name}.attributes = @params[\"\#{singular_name}\"]\n\n if @\#{singular_name}.save\n flash[\"notice\"] = \"\#{class_name} was succesfully updated\"\n redirect_to :action => \"show\#{suffix}/\" + @\#{singular_name}.id.to_s\n else\n render \"\#{singular_name}/edit\#{suffix}\"\n end\n end\n \n private\n def render\#{suffix}_scaffold(action = caller_method_name(caller))\n if template_exists?(\"\\\#{controller_name}/\\\#{action}\")\n render_action(action)\n else\n @scaffold_class = \#{class_name}\n @scaffold_singular_name, @scaffold_plural_name = \"\#{singular_name}\", \"\#{plural_name}\"\n @scaffold_suffix = \"\#{suffix}\"\n add_instance_variables_to_assigns\n\n @content_for_layout = @template.render_file(scaffold_path(action.sub(/\#{suffix}$/, \"\")), false)\n self.active_layout ? render_file(self.active_layout, \"200 OK\", true) : render_file(scaffold_path(\"layout\"))\n end\n end\n \n def scaffold_path(template_name)\n File.dirname(__FILE__) + \"/templates/scaffolds/\" + template_name + \".rhtml\"\n end\n \n def caller_method_name(caller)\n caller.first.scan(/`(.*)'/).first.first # ' ruby-mode\n end\n end_eval\nend\n", __FILE__, __LINE__ |