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 <<-"end_eval", __FILE__, __LINE__ def index list end end_eval end module_eval <<-"end_eval", __FILE__, __LINE__ def list#{suffix} @#{plural_name} = #{class_name}.find_all render#{suffix}_scaffold "list#{suffix}" end def show#{suffix} @#{singular_name} = #{class_name}.find(@params["id"]) render#{suffix}_scaffold end def destroy#{suffix} #{class_name}.find(@params["id"]).destroy redirect_to :action => "list#{suffix}" end def new#{suffix} @#{singular_name} = #{class_name}.new render#{suffix}_scaffold end def create#{suffix} @#{singular_name} = #{class_name}.new(@params["#{singular_name}"]) if @#{singular_name}.save flash["notice"] = "#{class_name} was succesfully created" redirect_to :action => "list#{suffix}" else render "#{singular_name}/new#{suffix}" end end def edit#{suffix} @#{singular_name} = #{class_name}.find(@params["id"]) render#{suffix}_scaffold end def update#{suffix} @#{singular_name} = #{class_name}.find(@params["#{singular_name}"]["id"]) @#{singular_name}.attributes = @params["#{singular_name}"] if @#{singular_name}.save flash["notice"] = "#{class_name} was succesfully updated" redirect_to :action => "show#{suffix}/" + @#{singular_name}.id.to_s else render "#{singular_name}/edit#{suffix}" end end private def render#{suffix}_scaffold(action = caller_method_name(caller)) if template_exists?("\#{controller_name}/\#{action}") render_action(action) else @scaffold_class = #{class_name} @scaffold_singular_name, @scaffold_plural_name = "#{singular_name}", "#{plural_name}" @scaffold_suffix = "#{suffix}" add_instance_variables_to_assigns @content_for_layout = @template.render_file(scaffold_path(action.sub(/#{suffix}$/, "")), false) self.active_layout ? render_file(self.active_layout, "200 OK", true) : render_file(scaffold_path("layout")) end end def scaffold_path(template_name) File.dirname(__FILE__) + "/templates/scaffolds/" + template_name + ".rhtml" end def caller_method_name(caller) caller.first.scan(/`(.*)'/).first.first # ' ruby-mode end end_eval end |