quirkey-qadmin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +44 -0
  3. data/PostInstall.txt +1 -0
  4. data/README.rdoc +64 -0
  5. data/Rakefile +28 -0
  6. data/init.rb +1 -0
  7. data/lib/qadmin/controller.rb +121 -0
  8. data/lib/qadmin/helper.rb +59 -0
  9. data/lib/qadmin/views/edit.html.erb +12 -0
  10. data/lib/qadmin/views/index.html.erb +31 -0
  11. data/lib/qadmin/views/new.html.erb +12 -0
  12. data/lib/qadmin/views/show.html.erb +14 -0
  13. data/lib/qadmin.rb +13 -0
  14. data/rails/init.rb +4 -0
  15. data/rails_generators/qadmin/USAGE +5 -0
  16. data/rails_generators/qadmin/qadmin_generator.rb +94 -0
  17. data/rails_generators/qadmin/templates/_form.html.erb +7 -0
  18. data/rails_generators/qadmin/templates/controller.rb +6 -0
  19. data/rails_generators/qadmin/templates/functional_test.rb +77 -0
  20. data/rails_generators/qadmin/templates/images/icon_destroy.png +0 -0
  21. data/rails_generators/qadmin/templates/images/icon_down.gif +0 -0
  22. data/rails_generators/qadmin/templates/images/icon_edit.png +0 -0
  23. data/rails_generators/qadmin/templates/images/icon_export.png +0 -0
  24. data/rails_generators/qadmin/templates/images/icon_find.png +0 -0
  25. data/rails_generators/qadmin/templates/images/icon_import.png +0 -0
  26. data/rails_generators/qadmin/templates/images/icon_list.png +0 -0
  27. data/rails_generators/qadmin/templates/images/icon_new.png +0 -0
  28. data/rails_generators/qadmin/templates/images/icon_next.gif +0 -0
  29. data/rails_generators/qadmin/templates/images/icon_prev.gif +0 -0
  30. data/rails_generators/qadmin/templates/images/icon_show.png +0 -0
  31. data/rails_generators/qadmin/templates/images/icon_sort.png +0 -0
  32. data/rails_generators/qadmin/templates/images/icon_up.gif +0 -0
  33. data/rails_generators/qadmin/templates/images/indicator_medium.gif +0 -0
  34. data/rails_generators/qadmin/templates/layout.html.erb +45 -0
  35. data/rails_generators/qadmin/templates/shoulda_functional_test.rb +33 -0
  36. data/rails_generators/qadmin/templates/style.css +683 -0
  37. data/script/console +10 -0
  38. data/script/destroy +14 -0
  39. data/script/generate +14 -0
  40. data/script/txt2html +71 -0
  41. data/test/test_generator_helper.rb +29 -0
  42. data/test/test_helper.rb +70 -0
  43. data/test/test_qadmin_controller.rb +138 -0
  44. data/test/test_qadmin_generator.rb +61 -0
  45. metadata +130 -0
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-01-07
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,44 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ init.rb
7
+ lib/qadmin.rb
8
+ lib/qadmin/controller.rb
9
+ lib/qadmin/helper.rb
10
+ lib/qadmin/views/edit.html.erb
11
+ lib/qadmin/views/index.html.erb
12
+ lib/qadmin/views/new.html.erb
13
+ lib/qadmin/views/show.html.erb
14
+ rails/init.rb
15
+ rails_generators/qadmin/USAGE
16
+ rails_generators/qadmin/qadmin_generator.rb
17
+ rails_generators/qadmin/templates/_form.html.erb
18
+ rails_generators/qadmin/templates/controller.rb
19
+ rails_generators/qadmin/templates/functional_test.rb
20
+ rails_generators/qadmin/templates/images/icon_destroy.png
21
+ rails_generators/qadmin/templates/images/icon_down.gif
22
+ rails_generators/qadmin/templates/images/icon_edit.png
23
+ rails_generators/qadmin/templates/images/icon_export.png
24
+ rails_generators/qadmin/templates/images/icon_find.png
25
+ rails_generators/qadmin/templates/images/icon_import.png
26
+ rails_generators/qadmin/templates/images/icon_list.png
27
+ rails_generators/qadmin/templates/images/icon_new.png
28
+ rails_generators/qadmin/templates/images/icon_next.gif
29
+ rails_generators/qadmin/templates/images/icon_prev.gif
30
+ rails_generators/qadmin/templates/images/icon_show.png
31
+ rails_generators/qadmin/templates/images/icon_sort.png
32
+ rails_generators/qadmin/templates/images/icon_up.gif
33
+ rails_generators/qadmin/templates/images/indicator_medium.gif
34
+ rails_generators/qadmin/templates/layout.html.erb
35
+ rails_generators/qadmin/templates/shoulda_functional_test.rb
36
+ rails_generators/qadmin/templates/style.css
37
+ script/console
38
+ script/destroy
39
+ script/generate
40
+ script/txt2html
41
+ test/test_generator_helper.rb
42
+ test/test_helper.rb
43
+ test/test_qadmin_controller.rb
44
+ test/test_qadmin_generator.rb
data/PostInstall.txt ADDED
@@ -0,0 +1 @@
1
+ For more information on qadmin, see http://github.com/quirkey/qadmin
data/README.rdoc ADDED
@@ -0,0 +1,64 @@
1
+ = qadmin
2
+
3
+ http://github.com/quirkey/qadmin
4
+
5
+ == DESCRIPTION:
6
+
7
+ An [almost] one command solution for adding admin interfaces/resources to a Rails app.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ Qadmin is a partial extraction of 2+ years of building Rails admin systems. A lot of the code comes from a Rails plugin I wrote (private) called quirkey_tools.
12
+
13
+ The system consists currently of two parts: a generator, and a set of macros.
14
+
15
+ The generator is =~ the Rails resource generator, but instead of plopping all the code for the different standard resource actions into the controller and templates, it uses the #qadmin macro to include the standard resource actions.
16
+
17
+ == SYNOPSIS:
18
+
19
+ (Coming soon)
20
+
21
+ == REQUIREMENTS:
22
+
23
+ Right now, a rails app, but the eventual goal is to make it framework agnostic (work with Sinatra, etc, too)..
24
+
25
+ == INSTALL:
26
+
27
+ Qadmin can be installed as a gem or a plugin.
28
+
29
+ === As a gem
30
+
31
+ sudo gem install qadmin --source=http://gems.github.com
32
+
33
+ Then in your config/environment.rb
34
+
35
+ config.gem 'qadmin'
36
+
37
+ === As a plugin
38
+
39
+ ./script/plugin install git://github.com/quirkey/qadmin.git
40
+
41
+ == LICENSE:
42
+
43
+ (The MIT License)
44
+
45
+ Copyright (c) 2009 Aaron Quint, Quirkey NYC, LLC
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of this software and associated documentation files (the
49
+ 'Software'), to deal in the Software without restriction, including
50
+ without limitation the rights to use, copy, modify, merge, publish,
51
+ distribute, sublicense, and/or sell copies of the Software, and to
52
+ permit persons to whom the Software is furnished to do so, subject to
53
+ the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be
56
+ included in all copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
59
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
61
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/qadmin'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('qadmin', Qadmin::VERSION) do |p|
7
+ p.developer('Aaron Quint', 'aaron@quirkey.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = 'quirkey'
11
+ p.extra_deps = [
12
+ ['activesupport','>= 2.2.0']
13
+ ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), "rails", "init")
@@ -0,0 +1,121 @@
1
+ module Qadmin
2
+ module Controller
3
+
4
+ module Macros
5
+
6
+ def qadmin(options = {})
7
+ self.cattr_accessor :model_name, :model_instance_name, :model_collection_name, :model_human_name, :available_actions
8
+ self.available_actions = [:index, :show, :new, :create, :edit, :update, :destroy]
9
+ self.available_actions = [options[:only]].flatten if options[:only]
10
+ self.available_actions -= [options[:exclude]].flatten if options[:exclude]
11
+ self.model_name = self.to_s.demodulize.gsub(/Controller/,'').singularize
12
+ self.model_instance_name = model_name.underscore
13
+ self.model_collection_name = model_instance_name.pluralize
14
+ self.model_human_name = model_instance_name.humanize
15
+ self.append_view_paths(File.join(File.dirname(__FILE__), 'views'))
16
+ define_admin_actions(available_actions, options)
17
+ end
18
+
19
+ private
20
+ def define_admin_actions(actions, options = {})
21
+ action_method_code = {
22
+ :index => %{
23
+ def index
24
+ @#{model_collection_name} = #{model_name}.paginate(:page => (params[:page] || 1))
25
+ respond_to do |format|
26
+ format.html
27
+ format.xml
28
+ end
29
+ end
30
+ },
31
+ :show => %{
32
+ def show
33
+ @#{model_instance_name} = #{model_name}.find(params[:id])
34
+ respond_to do |format|
35
+ format.html
36
+ format.xml
37
+ end
38
+ end
39
+ },
40
+ :new => %{
41
+ def new
42
+ @#{model_instance_name} = #{model_name}.new
43
+
44
+ respond_to do |format|
45
+ format.html # new.html.erb
46
+ format.xml { render :xml => @#{model_instance_name} }
47
+ end
48
+ end
49
+ },
50
+ :create => %{
51
+ def create
52
+ @#{model_instance_name} = #{model_name}.new(params[:#{model_instance_name}])
53
+ respond_to do |format|
54
+ if @#{model_instance_name}.save
55
+ flash[:message] = '#{model_human_name} was successfully created.'
56
+ format.html { redirect_to(#{model_instance_name}_path(@#{model_instance_name})) }
57
+ format.xml { render :xml => @#{model_instance_name}, :status => :created, :location => @#{model_instance_name} }
58
+ else
59
+ format.html { render :action => "new" }
60
+ format.xml { render :xml => @#{model_instance_name}.errors }
61
+ end
62
+ end
63
+ end
64
+ },
65
+ :edit => %{
66
+ def edit
67
+ @#{model_instance_name} = #{model_name}.find(params[:id])
68
+ end
69
+ },
70
+ :update => %{
71
+ def update
72
+ @#{model_instance_name} = #{model_name}.find(params[:id])
73
+
74
+ respond_to do |format|
75
+ if @#{model_instance_name}.update_attributes(params[:#{model_instance_name}])
76
+ flash[:message] = '#{model_human_name} was successfully updated.'
77
+ format.html { redirect_to(#{model_instance_name}_path(@#{model_instance_name})) }
78
+ format.xml { head :ok }
79
+ else
80
+ format.html { render :action => "edit" }
81
+ format.xml { render :xml => @#{model_instance_name}.errors }
82
+ end
83
+ end
84
+ end
85
+ },
86
+ :destroy => %{
87
+ def destroy
88
+ @#{model_instance_name} = #{model_name}.find(params[:id])
89
+ @#{model_instance_name}.destroy
90
+ flash[:message] = "#{model_human_name} \#{@#{model_instance_name}} was deleted"
91
+ respond_to do |format|
92
+ format.html { redirect_to(#{model_collection_name}_path) }
93
+ format.xml { head :ok }
94
+ end
95
+ end
96
+ }
97
+ }
98
+ action_code = actions.collect {|a| action_method_code[a.to_sym] }.join("\n")
99
+ self.class_eval(action_code)
100
+ end
101
+ end
102
+
103
+
104
+ # GET /<%= controller_file_path %>/new
105
+ # GET /<%= controller_file_path %>/new.xml
106
+
107
+ # GET /<%= controller_file_path %>/1/edit
108
+
109
+ # POST /<%= controller_file_path %>
110
+ # POST /<%= controller_file_path %>.xml
111
+
112
+ # PUT /<%= controller_file_path %>/1
113
+ # PUT /<%= controller_file_path %>/1.xml
114
+
115
+
116
+ # DELETE /<%= controller_file_path %>/1
117
+ # DELETE /<%= controller_file_path %>/1.xml
118
+
119
+
120
+ end
121
+ end
@@ -0,0 +1,59 @@
1
+ module Qadmin
2
+ module Helper
3
+
4
+ def fieldset(legend = nil, options = {}, &block)
5
+ content_tag(:fieldset, options) do
6
+ content_tag(:legend, legend) if legend
7
+ yield
8
+ end
9
+ end
10
+
11
+ def admin_controls(name, options = {}, &block)
12
+ return if respond_to?(:overlay?) && overlay?
13
+ controller = options[:controller] || name.to_s.tableize
14
+ assumed_object = self.instance_variable_get "@#{name}"
15
+ obj = options[:object] || assumed_object || nil
16
+ parent = options[:parent] || false
17
+
18
+ parent_link_attributes = parent ? {parent.class.to_s.foreign_key => parent.id} : {}
19
+ general_link_attributes = {:controller => controller}.merge(parent_link_attributes)
20
+
21
+ control_links = {
22
+ :index => link_to(image_tag('admin/icon_list.png') + " Back to List", general_link_attributes.merge(:action => 'index')),
23
+ :new => link_to(image_tag('admin/icon_new.png') + " New", general_link_attributes.merge(:action => 'new')),
24
+ :edit => link_to(image_tag('admin/icon_edit.png') + " Edit", general_link_attributes.merge(:action => 'edit', :id => obj)),
25
+ :show => link_to(image_tag('admin/icon_show.png') + " View", general_link_attributes.merge(:action => 'show', :id => obj)),
26
+ :destroy => link_to(image_tag('admin/icon_destroy.png') + " Delete", general_link_attributes.merge(:action => 'destroy', :id => obj), :confirm => 'Are you sure?', :method => :delete),
27
+ :ports => link_to(image_tag('admin/icon_export.png') + " Import/Export", general_link_attributes.merge(:action => 'ports'))
28
+ }
29
+
30
+ control_sets = {
31
+ :index => [:new],
32
+ :new => [:index],
33
+ :edit => [:index,:new,:show,:destroy],
34
+ :show => [:index,:new,:edit,:destroy]
35
+ }
36
+
37
+ control_set = (options[:for] ? control_sets[options[:for]] : options[:controls])
38
+ control_set << :ports if options[:ports]
39
+ controls = Array(control_set).collect {|c| control_links[c] }.compact
40
+
41
+ html = ""
42
+ html << %{<ul class="admin_controls">}
43
+ controls.each {|control| html << li(control) }
44
+ if block_given?
45
+ html << capture(&block)
46
+ html << %{</ul>}
47
+ concat(html,block.binding)
48
+ else
49
+ html << %{</ul>}
50
+ html
51
+ end
52
+ end
53
+
54
+ def alt_rows
55
+ %{class="#{cycle('alt', '')}"}
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ <h2>Editing <%= singular_name.humanize.capitalize %></h2>
2
+
3
+ <%%= admin_controls :<%= table_name %>, :for => :edit, :object => @<%= singular_name %> %>
4
+
5
+ <%%= error_messages_for :<%= singular_name %> %>
6
+
7
+ <%% form_for(@<%= singular_name %>) do |f| %>
8
+ <%%= render :partial => 'form', :locals => {:f => f, :<%= singular_name %> => @<%= singular_name %>} %>
9
+ <p><%%= f.submit "Update" %></p>
10
+ <%% end %>
11
+
12
+ <%%= admin_controls :<%= table_name %>, :for => :edit, :object => @<%= singular_name %> %>
@@ -0,0 +1,31 @@
1
+ <h2><%= plural_name.humanize.capitalize %></h2>
2
+
3
+ <%%= admin_controls :<%= table_name %>, :for => :index %>
4
+
5
+ <%%= will_paginate(@<%= plural_name %>) %>
6
+ <table>
7
+ <tr>
8
+ <% attributes.each_with_index do |attribute, i| -%>
9
+ <th<% if i == 0 -%> class="first_col"<% end -%>><%%= sorterable_link :<%= attribute.name -%> %></th>
10
+ <% end -%>
11
+ <th>View</th>
12
+ <th>Edit</th>
13
+ <th>Delete</th>
14
+ </tr>
15
+
16
+ <%% @<%= plural_name %>.each do |<%= singular_name %>| %>
17
+ <tr id="<%%= dom_id(<%= singular_name %>) %>" <%%= alt_rows %>>
18
+ <% attributes.each_with_index do |attribute, i| -%>
19
+ <% if i == 0 -%><td class="first_col"><%%= link_to <%= singular_name %>.<%= attribute.name %>, <%= table_name.singularize %>_path(<%= singular_name %>) %></td><%- else -%>
20
+ <td><%%= h <%= singular_name %>.<%= attribute.name %> %></td>
21
+ <%- end -%>
22
+ <% end -%>
23
+ <td><%%= link_to image_tag('admin/icon_show.png'), <%= table_name.singularize %>_path(<%= singular_name %>) %></td>
24
+ <td><%%= link_to image_tag('admin/icon_edit.png'), edit_<%= table_name.singularize %>_path(<%= singular_name %>) %></td>
25
+ <td><%%= link_to image_tag('admin/icon_destroy.png'), <%= table_name.singularize %>_path(<%= singular_name %>), :confirm => 'Are you sure?', :method => :delete %></td>
26
+ </tr>
27
+ <%% end %>
28
+ </table>
29
+ <%%= will_paginate(@<%= plural_name %>) %>
30
+
31
+ <%%= admin_controls :<%= table_name %>, :for => :index %>
@@ -0,0 +1,12 @@
1
+ <h2><%= singular_name.humanize.capitalize %>: New</h2>
2
+
3
+ <%%= admin_controls :<%= table_name %>, :for => :new %>
4
+
5
+ <%%= error_messages_for :<%= singular_name %> %>
6
+
7
+ <%% form_for(@<%= singular_name %>) do |f| %>
8
+ <%%= render :partial => 'form', :locals => {:f => f, :<%= singular_name %> => @<%= singular_name %>} %>
9
+ <p><%%= f.submit "Create" %></p>
10
+ <%% end %>
11
+
12
+ <%%= admin_controls :<%= table_name %>, :for => :new %>
@@ -0,0 +1,14 @@
1
+ <h2><%= plural_name.humanize.capitalize %>: <%%= @<%= singular_name %>.to_s %></h2>
2
+
3
+ <%%= admin_controls :<%= table_name %>, :for => :show, :object => @<%= singular_name %> %>
4
+
5
+ <div id="<%%= dom_id(@<%= singular_name %>) %>">
6
+ <div class="fields_group">
7
+ <% attributes.each do |attribute| -%>
8
+ <h5><%= attribute.human_name %>:</h5>
9
+ <%%=h @<%= singular_name %>.<%= attribute.name %> %>
10
+ <% end -%>
11
+ </div>
12
+ </div>
13
+
14
+ <%%= admin_controls :<%= table_name %>, :for => :show, :object => @<%= singular_name %> %>
data/lib/qadmin.rb ADDED
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ unless defined?(ActiveSupport)
5
+ require 'active_support'
6
+ end
7
+
8
+ module Qadmin
9
+ VERSION = '0.1.0'
10
+ end
11
+
12
+ require 'qadmin/helper'
13
+ require 'qadmin/controller'
data/rails/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'qadmin/qadmin')
2
+
3
+ ActionController::Base.send(:extend, Qadmin::Base)
4
+ ActionView::Base.send(:include, Qadmin::Helper)
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -0,0 +1,94 @@
1
+ class QadminGenerator < Rails::Generator::NamedBase
2
+ attr_reader :controller_name,
3
+ :controller_class_path,
4
+ :controller_file_path,
5
+ :controller_class_nesting,
6
+ :controller_class_nesting_depth,
7
+ :controller_class_name,
8
+ :controller_singular_name,
9
+ :controller_plural_name
10
+ alias_method :controller_file_name, :controller_singular_name
11
+ alias_method :controller_table_name, :controller_plural_name
12
+
13
+ def initialize(runtime_args, runtime_options = {})
14
+ super
15
+
16
+ @controller_name = @args.shift || @name.pluralize
17
+
18
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
19
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
20
+
21
+ if @controller_class_nesting.empty?
22
+ @controller_class_name = @controller_class_name_without_nesting
23
+ else
24
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
25
+ end
26
+ end
27
+
28
+ def manifest
29
+ record do |m|
30
+ klass # checks for class definition
31
+ # Check for class naming collisions.
32
+ m.class_collisions(controller_class_path, "#{controller_class_name}Controller")
33
+
34
+ # Controller, helper, views, and test directories.
35
+ m.directory(File.join('app','controllers', controller_class_path))
36
+ m.directory(File.join('app', 'helpers', controller_class_path))
37
+ m.directory(File.join('app', 'views', controller_class_path, controller_file_name))
38
+ m.directory(File.join('test', 'functional', controller_class_path))
39
+ m.directory(File.join('public','images','admin'))
40
+
41
+ #copy form over too
42
+ m.template("_form.html.erb",File.join('app','views', controller_class_path, controller_file_name, "_form.html.erb"))
43
+
44
+ # Layout and stylesheet.
45
+ m.template('layout.html.erb', File.join('app','views','layouts', "admin.html.erb"))
46
+ m.template('style.css', 'public/stylesheets/admin.css')
47
+
48
+ m.template(
49
+ 'controller.rb', File.join('app','controllers', controller_class_path, "#{controller_file_name}_controller.rb")
50
+ )
51
+
52
+ m.template('shoulda_functional_test.rb', File.join('test','functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
53
+
54
+ m.route_resources controller_file_name
55
+
56
+ # Copy Icons
57
+ Dir[File.join(File.dirname(__FILE__),'templates','images/*')].each do |image|
58
+ m.file File.join('images',File.basename(image)), File.join('public','images','admin',File.basename(image))
59
+ end
60
+
61
+ end
62
+ end
63
+
64
+ protected
65
+ # Override with your own usage banner.
66
+ def banner
67
+ "Usage: #{$0} qadmin ModelName"
68
+ end
69
+
70
+ def scaffold_views
71
+ %w[ index show new edit ]
72
+ end
73
+
74
+ def model_name
75
+ class_name.demodulize
76
+ end
77
+
78
+ def klass
79
+ begin
80
+ require "#{file_name}" unless defined?(model_name.constantize)
81
+ rescue
82
+ raise "You must define the class #{model_name} before running qscaffold"
83
+ end
84
+ model_name.constantize
85
+ end
86
+
87
+ def attributes
88
+ klass.content_columns
89
+ end
90
+
91
+ def ignore_attributes
92
+ %w{created_at updated_at}.push klass.protected_attributes
93
+ end
94
+ end
@@ -0,0 +1,7 @@
1
+ <%% fieldset do %>
2
+ <% attributes.each do |attribute| -%>
3
+ <% unless ignore_attributes.include?(attribute.name) -%>
4
+ <p><label><%= attribute.human_name %></label><%%= f.text_field :<%= attribute.name %> %></p>
5
+ <% end -%>
6
+ <% end -%>
7
+ <%% end %>
@@ -0,0 +1,6 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ #before_filter :login_required
3
+ #layout 'admin'
4
+ qadmin
5
+
6
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../test_helper'
2
+ require '<%= controller_file_path %>_controller'
3
+
4
+ # Re-raise errors caught by the controller.
5
+ class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
6
+
7
+ class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
8
+ fixtures :<%= model_name.tableize %>#, :users
9
+
10
+ def setup
11
+ @controller = <%= controller_class_name %>Controller.new
12
+ @request = ActionController::TestRequest.new
13
+ @response = ActionController::TestResponse.new
14
+ #login_as(:aaron)
15
+ @<%= file_name %> = <%= model_name.tableize %>(!!FIXTURENAME)
16
+ end
17
+
18
+ # def test_should_require_login
19
+ # logout
20
+ # get :index
21
+ # assert_redirected_to_login
22
+ # end
23
+
24
+ def test_should_get_index
25
+ get :index
26
+ assert_response :success
27
+ assert assigns(:<%= model_name.tableize %>)
28
+ end
29
+
30
+ def test_should_get_new
31
+ get :new
32
+ assert_response :success
33
+ assert_select 'form'
34
+ end
35
+
36
+ def test_should_create_<%= file_name %>
37
+ assert_difference '<%= model_name %>.count' do
38
+ post :create, :<%= file_name %> => <%= file_name %>_params
39
+ assert_redirected_to <%= table_name.singularize %>_path(assigns(:<%= file_name %>))
40
+ end
41
+ end
42
+
43
+ def test_should_show_<%= file_name %>
44
+ get :show, :id => @<%= file_name %>.id
45
+ assert_response :success
46
+ assert assigns(:<%= file_name %>)
47
+ end
48
+
49
+ def test_should_get_edit
50
+ get :edit, :id => @<%= file_name %>.id
51
+ assert_response :success
52
+ assert assigns(:<%= file_name %>)
53
+ assert_select 'form'
54
+ end
55
+
56
+ def test_should_update_<%= file_name %>
57
+ assert_no_difference '<%= model_name %>.count' do
58
+ put :update, :id => @<%= file_name %>.id, :<%= file_name %> => <%= file_name %>_params
59
+ assert_redirected_to <%= table_name.singularize %>_path(assigns(:<%= file_name %>))
60
+ end
61
+ end
62
+
63
+ def test_should_destroy_<%= file_name %>
64
+ assert_difference '<%= model_name %>.count', -1 do
65
+ delete :destroy, :id => @<%= file_name %>.id
66
+ assert_redirected_to <%= table_name %>_path
67
+ end
68
+ end
69
+
70
+
71
+ protected
72
+ def <%= file_name %>_params(options = {})
73
+ {
74
+ <%= attributes.collect { |a| ":#{a.name} => #{a.default}" }.join(', ') %>
75
+ }.update(options)
76
+ end
77
+ end