Ticket #7700: scaffolding_plugin.diff
| File scaffolding_plugin.diff, 18.6 kB (added by josh, 2 years ago) |
|---|
-
plugins/scaffolding/test/scaffolding_test.rb
old new 1 require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb')) 2 require 'action_controller/test_process' 3 require 'active_record/fixtures' 4 5 ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:") 6 7 ActiveRecord::Schema.define(:version => 1) do 8 create_table :entries do |t| 9 t.column :title, :string 10 t.column :body, :text 11 t.column :created_at, :datetime 12 t.column :updated_at, :datetime 13 end 14 end 15 16 class Entry < ActiveRecord::Base 17 end 18 19 class WeblogController < ActionController::Base 20 scaffold :entry 21 end 22 23 class ScaffoldingTest < Test::Unit::TestCase 24 def setup 25 @controller = WeblogController.new 26 @request = ActionController::TestRequest.new 27 @response = ActionController::TestResponse.new 28 29 @first = Entry.create :title => "Welcome to the weblog", :body => "Such a lovely day" 30 end 31 32 def test_should_get_index 33 get :index 34 assert_response :success 35 end 36 37 def test_should_get_list 38 get :list 39 assert_response :success 40 assert assigns(:entries) 41 end 42 43 def test_should_show_entry 44 get :show, :id => @first.id 45 assert_response :success 46 end 47 48 def test_should_get_new 49 get :new 50 assert_response :success 51 end 52 53 def test_should_create_entry 54 old_count = Entry.count 55 post :create, :entry => { } 56 assert_equal old_count+1, Entry.count 57 58 assert_redirected_to :action => 'list' 59 end 60 61 def test_should_get_edit 62 get :edit, :id => @first.id 63 assert_response :success 64 end 65 66 def test_should_update_entry 67 post :update, :id => @first.id 68 assert_redirected_to :action => 'show', :id => @first.id 69 end 70 71 def test_should_destroy_entry 72 old_count = Entry.count 73 post :destroy, :id => @first.id 74 assert_equal old_count-1, Entry.count 75 76 assert_redirected_to :action => 'list' 77 end 78 end -
plugins/scaffolding/Rakefile
old new 1 require 'rake' 2 require 'rake/testtask' 3 require 'rake/rdoctask' 4 5 desc 'Default: run unit tests.' 6 task :default => :test 7 8 desc 'Test the scaffolding plugin.' 9 Rake::TestTask.new(:test) do |t| 10 t.libs << 'lib' 11 t.pattern = 'test/**/*_test.rb' 12 t.verbose = true 13 end 14 15 desc 'Generate documentation for the scaffolding plugin.' 16 Rake::RDocTask.new(:rdoc) do |rdoc| 17 rdoc.rdoc_dir = 'rdoc' 18 rdoc.title = 'Scaffolding' 19 rdoc.options << '--line-numbers' << '--inline-source' 20 rdoc.rdoc_files.include('README') 21 rdoc.rdoc_files.include('lib/**/*.rb') 22 end -
plugins/scaffolding/init.rb
old new -
plugins/scaffolding/lib/scaffolding.rb
old new 1 module Scaffolding # :nodoc: 2 def self.included(base) 3 base.extend(ClassMethods) 4 end 5 6 # Scaffolding is a way to quickly put an Active Record class online by providing a series of standardized actions 7 # for listing, showing, creating, updating, and destroying objects of the class. These standardized actions come 8 # with both controller logic and default templates that through introspection already know which fields to display 9 # and which input types to use. Example: 10 # 11 # class WeblogController < ActionController::Base 12 # scaffold :entry 13 # end 14 # 15 # This tiny piece of code will add all of the following methods to the controller: 16 # 17 # class WeblogController < ActionController::Base 18 # verify :method => :post, :only => [ :destroy, :create, :update ], 19 # :redirect_to => { :action => :list } 20 # 21 # def index 22 # list 23 # end 24 # 25 # def list 26 # @entries = Entry.find(:all) 27 # render_scaffold "list" 28 # end 29 # 30 # def show 31 # @entry = Entry.find(params[:id]) 32 # render_scaffold 33 # end 34 # 35 # def destroy 36 # Entry.find(params[:id]).destroy 37 # redirect_to :action => "list" 38 # end 39 # 40 # def new 41 # @entry = Entry.new 42 # render_scaffold 43 # end 44 # 45 # def create 46 # @entry = Entry.new(params[:entry]) 47 # if @entry.save 48 # flash[:notice] = "Entry was successfully created" 49 # redirect_to :action => "list" 50 # else 51 # render_scaffold('new') 52 # end 53 # end 54 # 55 # def edit 56 # @entry = Entry.find(params[:id]) 57 # render_scaffold 58 # end 59 # 60 # def update 61 # @entry = Entry.find(params[:id]) 62 # @entry.attributes = params[:entry] 63 # 64 # if @entry.save 65 # flash[:notice] = "Entry was successfully updated" 66 # redirect_to :action => "show", :id => @entry 67 # else 68 # render_scaffold('edit') 69 # end 70 # end 71 # end 72 # 73 # The <tt>render_scaffold</tt> method will first check to see if you've made your own template (like "weblog/show.erb" for 74 # the show action) and if not, then render the generic template for that action. This gives you the possibility of using the 75 # scaffold while you're building your specific application. Start out with a totally generic setup, then replace one template 76 # and one action at a time while relying on the rest of the scaffolded templates and actions. 77 module ClassMethods 78 # Adds a swath of generic CRUD actions to the controller. The +model_id+ is automatically converted into a class name unless 79 # one is specifically provide through <tt>options[:class_name]</tt>. So <tt>scaffold :post</tt> would use Post as the class 80 # and @post/@posts for the instance variables. 81 # 82 # It's possible to use more than one scaffold in a single controller by specifying <tt>options[:suffix] = true</tt>. This will 83 # make <tt>scaffold :post, :suffix => true</tt> use method names like list_post, show_post, and create_post 84 # instead of just list, show, and post. If suffix is used, then no index method is added. 85 def scaffold(model_id, options = {}) 86 options.assert_valid_keys(:class_name, :suffix) 87 88 singular_name = model_id.to_s 89 class_name = options[:class_name] || singular_name.camelize 90 plural_name = singular_name.pluralize 91 suffix = options[:suffix] ? "_#{singular_name}" : "" 92 93 unless options[:suffix] 94 module_eval <<-"end_eval", __FILE__, __LINE__ 95 def index 96 list 97 end 98 end_eval 99 end 100 101 module_eval <<-"end_eval", __FILE__, __LINE__ 102 103 verify :method => :post, :only => [ :destroy#{suffix}, :create#{suffix}, :update#{suffix} ], 104 :redirect_to => { :action => :list#{suffix} } 105 106 107 def list#{suffix} 108 @#{singular_name}_pages, @#{plural_name} = paginate :#{plural_name}, :per_page => 10 109 render#{suffix}_scaffold "list#{suffix}" 110 end 111 112 def show#{suffix} 113 @#{singular_name} = #{class_name}.find(params[:id]) 114 render#{suffix}_scaffold 115 end 116 117 def destroy#{suffix} 118 #{class_name}.find(params[:id]).destroy 119 redirect_to :action => "list#{suffix}" 120 end 121 122 def new#{suffix} 123 @#{singular_name} = #{class_name}.new 124 render#{suffix}_scaffold 125 end 126 127 def create#{suffix} 128 @#{singular_name} = #{class_name}.new(params[:#{singular_name}]) 129 if @#{singular_name}.save 130 flash[:notice] = "#{class_name} was successfully created" 131 redirect_to :action => "list#{suffix}" 132 else 133 render#{suffix}_scaffold('new') 134 end 135 end 136 137 def edit#{suffix} 138 @#{singular_name} = #{class_name}.find(params[:id]) 139 render#{suffix}_scaffold 140 end 141 142 def update#{suffix} 143 @#{singular_name} = #{class_name}.find(params[:id]) 144 @#{singular_name}.attributes = params[:#{singular_name}] 145 146 if @#{singular_name}.save 147 flash[:notice] = "#{class_name} was successfully updated" 148 redirect_to :action => "show#{suffix}", :id => @#{singular_name} 149 else 150 render#{suffix}_scaffold('edit') 151 end 152 end 153 154 private 155 def render#{suffix}_scaffold(action=nil) 156 action ||= caller_method_name(caller) 157 # logger.info ("testing template:" + "\#{self.class.controller_path}/\#{action}") if logger 158 159 if template_exists?("\#{self.class.controller_path}/\#{action}") 160 render :action => action 161 else 162 @scaffold_class = #{class_name} 163 @scaffold_singular_name, @scaffold_plural_name = "#{singular_name}", "#{plural_name}" 164 @scaffold_suffix = "#{suffix}" 165 add_instance_variables_to_assigns 166 167 @template.instance_variable_set("@content_for_layout", @template.render_file(scaffold_path(action.sub(/#{suffix}$/, "")), false)) 168 169 if !active_layout.nil? 170 render :file => active_layout, :use_full_path => true 171 else 172 render :file => scaffold_path('layout') 173 end 174 end 175 end 176 177 def scaffold_path(template_name) 178 File.dirname(__FILE__) + "/templates/" + template_name + ".erb" 179 end 180 181 def caller_method_name(caller) 182 caller.first.scan(/`(.*)'/).first.first # ' ruby-mode 183 end 184 end_eval 185 end 186 end 187 end -
plugins/scaffolding/lib/templates/new.erb
old new 1 <h1>New <%= @scaffold_singular_name %></h1> 2 3 <%= error_messages_for(@scaffold_singular_name) %> 4 <%= form(@scaffold_singular_name, :action => "create#{@scaffold_suffix}") %> 5 6 <%= link_to "Back", :action => "list#{@scaffold_suffix}" %> -
plugins/scaffolding/lib/templates/list.erb
old new 1 <h1>Listing <%= @scaffold_plural_name %></h1> 2 3 <table> 4 <tr> 5 <% for column in @scaffold_class.content_columns %> 6 <th><%= column.human_name %></th> 7 <% end %> 8 </tr> 9 10 <% for entry in instance_variable_get("@#{@scaffold_plural_name}") %> 11 <tr> 12 <% for column in @scaffold_class.content_columns %> 13 <td><%= entry.send(column.name) %></td> 14 <% end %> 15 <td><%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => entry %></td> 16 <td><%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => entry %></td> 17 <td><%= link_to "Destroy", {:action => "destroy#{@scaffold_suffix}", :id => entry}, { :confirm => "Are you sure?", :method => :post } %></td> 18 </tr> 19 <% end %> 20 </table> 21 22 <%= link_to "Previous page", { :page => instance_variable_get("@#{@scaffold_singular_name}_pages").current.previous } if instance_variable_get("@#{@scaffold_singular_name}_pages").current.previous %> 23 <%= link_to "Next page", { :page => instance_variable_get("@#{@scaffold_singular_name}_pages").current.next } if instance_variable_get("@#{@scaffold_singular_name}_pages").current.next %> 24 25 <br /> 26 27 <%= link_to "New #{@scaffold_singular_name}", :action => "new#{@scaffold_suffix}" %> -
plugins/scaffolding/lib/templates/layout.erb
old new 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 2 "http://www.w3.org/TR/html4/loose.dtd"> 3 <html> 4 <head> 5 <title>Scaffolding</title> 6 <style> 7 body { background-color: #fff; color: #333; } 8 9 body, p, ol, ul, td { 10 font-family: verdana, arial, helvetica, sans-serif; 11 font-size: 13px; 12 line-height: 18px; 13 } 14 15 pre { 16 background-color: #eee; 17 padding: 10px; 18 font-size: 11px; 19 } 20 21 a { color: #000; } 22 a:visited { color: #666; } 23 a:hover { color: #fff; background-color:#000; } 24 25 .fieldWithErrors { 26 padding: 2px; 27 background-color: red; 28 display: table; 29 } 30 31 #errorExplanation { 32 width: 400px; 33 border: 2px solid red; 34 padding: 7px; 35 padding-bottom: 12px; 36 margin-bottom: 20px; 37 background-color: #f0f0f0; 38 } 39 40 #errorExplanation h2 { 41 text-align: left; 42 font-weight: bold; 43 padding: 5px 5px 5px 15px; 44 font-size: 12px; 45 margin: -7px; 46 background-color: #c00; 47 color: #fff; 48 } 49 50 #errorExplanation p { 51 color: #333; 52 margin-bottom: 0; 53 padding: 5px; 54 } 55 56 #errorExplanation ul li { 57 font-size: 12px; 58 list-style: square; 59 } 60 </style> 61 </head> 62 <body> 63 64 <p style="color: green"><%= flash[:notice] %></p> 65 66 <%= yield %> 67 68 </body> 69 </html> -
plugins/scaffolding/lib/templates/show.erb
old new 1 <% for column in @scaffold_class.content_columns %> 2 <p> 3 <b><%= column.human_name %>:</b> 4 <%= instance_variable_get("@#{@scaffold_singular_name}").send(column.name) %> 5 </p> 6 <% end %> 7 8 <%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => instance_variable_get("@#{@scaffold_singular_name}") %> | 9 <%= link_to "Back", :action => "list#{@scaffold_suffix}" %> -
plugins/scaffolding/lib/templates/edit.erb
old new 1 <h1>Editing <%= @scaffold_singular_name %></h1> 2 3 <%= error_messages_for(@scaffold_singular_name) %> 4 <%= form(@scaffold_singular_name, :action => "update#{@scaffold_suffix}") %> 5 6 <%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => instance_variable_get("@#{@scaffold_singular_name}") %> | 7 <%= link_to "Back", :action => "list#{@scaffold_suffix}" %> -
plugins/scaffolding/MIT-LICENSE
old new 1 Copyright (c) 2004-2007 David Heinemeier Hansson 2 3 Permission is hereby granted, free of charge, to any person obtaining 4 a copy of this software and associated documentation files (the 5 "Software"), to deal in the Software without restriction, including 6 without limitation the rights to use, copy, modify, merge, publish, 7 distribute, sublicense, and/or sell copies of the Software, and to 8 permit persons to whom the Software is furnished to do so, subject to 9 the following conditions: 10 11 The above copyright notice and this permission notice shall be 12 included in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -
plugins/scaffolding/README
old new 1 Scaffolding 2 =========== 3 4 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: 5 6 The render_scaffold method will first check to see if you've made your own template (like "weblog/show.erb" 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. 7 8 Example 9 ======= 10 11 class WeblogController < ActionController::Base 12 scaffold :entry 13 end 14 15 This tiny piece of code will add all of the following methods to the controller: 16 17 class WeblogController < ActionController::Base 18 verify :method => :post, :only => [ :destroy, :create, :update ], 19 :redirect_to => { :action => :list } 20 21 def index 22 list 23 end 24 25 def list 26 @entries = Entry.find(:all) 27 render_scaffold "list" 28 end 29 30 def show 31 @entry = Entry.find(params[:id]) 32 render_scaffold 33 end 34 35 def destroy 36 Entry.find(params[:id]).destroy 37 redirect_to :action => "list" 38 end 39 40 def new 41 @entry = Entry.new 42 render_scaffold 43 end 44 45 def create 46 @entry = Entry.new(params[:entry]) 47 if @entry.save 48 flash[:notice] = "Entry was successfully created" 49 redirect_to :action => "list" 50 else 51 render_scaffold('new') 52 end 53 end 54 55 def edit 56 @entry = Entry.find(params[:id]) 57 render_scaffold 58 end 59 60 def update 61 @entry = Entry.find(params[:id]) 62 @entry.attributes = params[:entry] 63 64 if @entry.save 65 flash[:notice] = "Entry was successfully updated" 66 redirect_to :action => "show", :id => @entry 67 else 68 render_scaffold('edit') 69 end 70 end 71 end 72 73 74 Copyright (c) 2004-2007 David Heinemeier Hansson, released under the MIT license