view_mapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README +116 -0
  5. data/Rakefile +57 -0
  6. data/VERSION +1 -0
  7. data/generators/scaffold_for_view/USAGE +1 -0
  8. data/generators/scaffold_for_view/scaffold_for_view_generator.rb +37 -0
  9. data/generators/view_for/USAGE +1 -0
  10. data/generators/view_for/view_for_generator.rb +85 -0
  11. data/lib/view_mapper/auto_complete_templates/controller.rb +88 -0
  12. data/lib/view_mapper/auto_complete_templates/functional_test.rb +45 -0
  13. data/lib/view_mapper/auto_complete_templates/helper.rb +2 -0
  14. data/lib/view_mapper/auto_complete_templates/helper_test.rb +4 -0
  15. data/lib/view_mapper/auto_complete_templates/layout.html.erb +18 -0
  16. data/lib/view_mapper/auto_complete_templates/style.css +54 -0
  17. data/lib/view_mapper/auto_complete_templates/view_edit.html.erb +21 -0
  18. data/lib/view_mapper/auto_complete_templates/view_index.html.erb +24 -0
  19. data/lib/view_mapper/auto_complete_templates/view_new.html.erb +20 -0
  20. data/lib/view_mapper/auto_complete_templates/view_show.html.erb +10 -0
  21. data/lib/view_mapper/auto_complete_view.rb +44 -0
  22. data/lib/view_mapper/editable_manifest.rb +10 -0
  23. data/lib/view_mapper/route_action.rb +32 -0
  24. data/lib/view_mapper/view_mapper.rb +33 -0
  25. data/lib/view_mapper.rb +4 -0
  26. data/test/auto_complete_test.rb +146 -0
  27. data/test/database.yml +3 -0
  28. data/test/editable_manifest_test.rb +32 -0
  29. data/test/expected_templates/auto_complete/edit.html.erb +23 -0
  30. data/test/expected_templates/auto_complete/expected_routes.rb +45 -0
  31. data/test/expected_templates/auto_complete/index.html.erb +24 -0
  32. data/test/expected_templates/auto_complete/new.html.erb +22 -0
  33. data/test/expected_templates/auto_complete/show.html.erb +18 -0
  34. data/test/expected_templates/auto_complete/standard_routes.rb +43 -0
  35. data/test/expected_templates/auto_complete/testies.html.erb +18 -0
  36. data/test/expected_templates/auto_complete/testies_controller.rb +88 -0
  37. data/test/fake/fake_generator.rb +3 -0
  38. data/test/fake_view.rb +7 -0
  39. data/test/rails_generator/base.rb +266 -0
  40. data/test/rails_generator/commands.rb +621 -0
  41. data/test/rails_generator/generated_attribute.rb +46 -0
  42. data/test/rails_generator/generators/components/scaffold/scaffold_generator.rb +102 -0
  43. data/test/rails_generator/lookup.rb +249 -0
  44. data/test/rails_generator/manifest.rb +53 -0
  45. data/test/rails_generator/options.rb +150 -0
  46. data/test/rails_generator/scripts/destroy.rb +29 -0
  47. data/test/rails_generator/scripts/generate.rb +7 -0
  48. data/test/rails_generator/scripts/update.rb +12 -0
  49. data/test/rails_generator/scripts.rb +89 -0
  50. data/test/rails_generator/secret_key_generator.rb +24 -0
  51. data/test/rails_generator/simple_logger.rb +46 -0
  52. data/test/rails_generator/spec.rb +44 -0
  53. data/test/rails_generator.rb +43 -0
  54. data/test/scaffold_for_view_generator_test.rb +77 -0
  55. data/test/test_helper.rb +43 -0
  56. data/test/view_for_generator_test.rb +93 -0
  57. data/test/view_mapper_test.rb +29 -0
  58. data/view_mapper.gemspec +125 -0
  59. metadata +147 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Pat Shaughnessy
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.
data/README ADDED
@@ -0,0 +1,116 @@
1
+ View_mapper: Generate complex view code for your models.
2
+
3
+ See: http://patshaughnessy.net/view_mapper for more details.
4
+
5
+ Two generators are provided:
6
+
7
+ 1. view_for: This will generate the specified view code for an existing model.
8
+
9
+ script/generate view_for model [ --view view:view_parameter ]
10
+
11
+ View_for generates HTML fields for each of the specified model's columns.
12
+ If no view is specified, standard Rails scaffolding code will be generated.
13
+
14
+ 2. scaffold_for_view: The same as view_for, except that it will also generate the
15
+ model code files as well. If no view is specified, this generator is identical to
16
+ the standard Rails scaffold generator.
17
+
18
+ script/generate scaffold_for_view model [ --view view:view_parameter ]
19
+
20
+
21
+
22
+
23
+ Right now, one custom view is provided:
24
+
25
+ 1. auto_complete: Generates view code that uses the standard Rails auto_complete plugin
26
+ for type ahead behavior.
27
+
28
+ ... more views to come!
29
+
30
+
31
+
32
+ Examples:
33
+ ---------
34
+
35
+ - Generate standard Rails scaffolding for an existing model called "widget":
36
+
37
+ ./script/generate view_for widget
38
+ exists app/controllers/
39
+ exists app/helpers/
40
+ create app/views/widgets
41
+ exists app/views/layouts/
42
+ exists test/functional/
43
+ exists test/unit/
44
+ exists test/unit/helpers/
45
+ exists public/stylesheets/
46
+ create app/views/widgets/index.html.erb
47
+ create app/views/widgets/show.html.erb
48
+ create app/views/widgets/new.html.erb
49
+ create app/views/widgets/edit.html.erb
50
+ create app/views/layouts/widgets.html.erb
51
+ identical public/stylesheets/scaffold.css
52
+ create app/controllers/widgets_controller.rb
53
+ create test/functional/widgets_controller_test.rb
54
+ create app/helpers/widgets_helper.rb
55
+ create test/unit/helpers/widgets_helper_test.rb
56
+ route map.resources :widgets
57
+
58
+ - Generate scaffolding for an existing "office" model with auto complete on the "address" field:
59
+
60
+ ./script/generate view_for office --view auto_complete:address
61
+ exists app/controllers/
62
+ exists app/helpers/
63
+ create app/views/offices
64
+ exists app/views/layouts/
65
+ exists test/functional/
66
+ exists test/unit/
67
+ exists test/unit/helpers/
68
+ exists public/stylesheets/
69
+ create app/views/offices/index.html.erb
70
+ create app/views/offices/show.html.erb
71
+ create app/views/offices/new.html.erb
72
+ create app/views/offices/edit.html.erb
73
+ create app/views/layouts/offices.html.erb
74
+ identical public/stylesheets/scaffold.css
75
+ create app/controllers/offices_controller.rb
76
+ create test/functional/offices_controller_test.rb
77
+ create app/helpers/offices_helper.rb
78
+ create test/unit/helpers/offices_helper_test.rb
79
+ route map.resources :offices
80
+ route map.connect 'auto_complete_for_office_address', :controller => 'offices', :action => 'auto_complete_for_office_address'
81
+
82
+ - Generate a new model called "group" containing two fields "name" and "column"
83
+ and also implement auto complete on the "name" column:
84
+
85
+ ./script/generate scaffold_for_view group name:string count:integer --view auto_complete:name
86
+ exists app/models/
87
+ exists app/controllers/
88
+ exists app/helpers/
89
+ create app/views/groups
90
+ exists app/views/layouts/
91
+ exists test/functional/
92
+ exists test/unit/
93
+ exists test/unit/helpers/
94
+ exists public/stylesheets/
95
+ create app/views/groups/index.html.erb
96
+ create app/views/groups/show.html.erb
97
+ create app/views/groups/new.html.erb
98
+ create app/views/groups/edit.html.erb
99
+ create app/views/layouts/groups.html.erb
100
+ identical public/stylesheets/scaffold.css
101
+ create app/controllers/groups_controller.rb
102
+ create test/functional/groups_controller_test.rb
103
+ create app/helpers/groups_helper.rb
104
+ create test/unit/helpers/groups_helper_test.rb
105
+ route map.resources :groups
106
+ dependency model
107
+ exists app/models/
108
+ exists test/unit/
109
+ exists test/fixtures/
110
+ create app/models/group.rb
111
+ create test/unit/group_test.rb
112
+ create test/fixtures/groups.yml
113
+ exists db/migrate
114
+ create db/migrate/20090930171024_create_groups.rb
115
+ route map.connect 'auto_complete_for_group_name', :controller => 'groups', :action => 'auto_complete_for_group_name'
116
+
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "view_mapper"
8
+ gem.summary = %Q{Generate complex view code for your models}
9
+ gem.description = %Q{Generate complex view code for your models}
10
+ gem.email = "pat@patshaughnessy.net"
11
+ gem.homepage = "http://github.com/patshaughnessy/view_mapper"
12
+ gem.authors = ["Pat Shaughnessy"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ if File.exist?('VERSION')
48
+ version = File.read('VERSION')
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "view_mapper #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1 @@
1
+ script/generate scaffold_for_view model [ --view view:view_parameter ]
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../../lib/view_mapper'
2
+
3
+ class ScaffoldForViewGenerator < ScaffoldGenerator
4
+
5
+ include ViewMapper
6
+
7
+ attr_accessor :valid
8
+
9
+ def initialize(runtime_args, runtime_options = {})
10
+ super
11
+ @source_root = source_root_for_view
12
+ validate
13
+ end
14
+
15
+ def source_root_for_view
16
+ self.class.lookup('scaffold').path + "/templates"
17
+ end
18
+
19
+ def validate
20
+ @valid = true
21
+ end
22
+
23
+ def record
24
+ EditableManifest.new(self) { |m| yield m }
25
+ end
26
+
27
+ def manifest
28
+ super.edit do |action|
29
+ action unless !@valid
30
+ end
31
+ end
32
+
33
+ def banner
34
+ "script/generate scaffold_for_view model [ --view view:view_parameter ]"
35
+ end
36
+
37
+ end
@@ -0,0 +1 @@
1
+ script/generate view_for model [ --view view:view_parameter ]
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/../../lib/view_mapper'
2
+
3
+ class ViewForGenerator < ScaffoldGenerator
4
+
5
+ include ViewMapper
6
+
7
+ attr_reader :model
8
+ attr_accessor :valid
9
+
10
+ BUILT_IN_COLUMNS = [ 'id', 'created_at', 'updated_at' ]
11
+
12
+ def initialize(runtime_args, runtime_options = {})
13
+ super
14
+ @source_root = source_root_for_view
15
+ find_model @name
16
+ @columns = custom_columns unless model.nil?
17
+ validate
18
+ end
19
+
20
+ def source_root_for_view
21
+ self.class.lookup('scaffold').path + "/templates"
22
+ end
23
+
24
+ def find_model(model_name)
25
+ @model = nil
26
+ begin
27
+ @model = Object.const_get model_name.camelize
28
+ if !model.new.kind_of? ActiveRecord::Base
29
+ logger.error "Class '#{model_name}' is not an ActiveRecord::Base."
30
+ @model = nil
31
+ end
32
+ rescue NameError
33
+ logger.error "Class '#{model_name}' does not exist."
34
+ rescue ActiveRecord::StatementInvalid
35
+ logger.error "Table for model '#{model_name}' does not exist - run rake db:migrate first."
36
+ end
37
+ end
38
+
39
+ def custom_columns
40
+ @model.columns.reject do |col|
41
+ BUILT_IN_COLUMNS.include? col.name
42
+ end
43
+ end
44
+
45
+ def record
46
+ EditableManifest.new(self) { |m| yield m }
47
+ end
48
+
49
+ def manifest
50
+ super.edit do |action|
51
+ action unless is_model_action(action) || !valid
52
+ end
53
+ end
54
+
55
+ def is_model_action(action)
56
+ is_create_model_dir_action(action) || is_model_dependency_action(action)
57
+ end
58
+
59
+ def is_create_model_dir_action(action)
60
+ action[0] == :directory && action[1].include?('app/models/')
61
+ end
62
+
63
+ def is_model_dependency_action(action)
64
+ action[0] == :dependency && action[1].include?('model')
65
+ end
66
+
67
+ def attributes
68
+ @attributes_from_columns ||= attributes_from_columns
69
+ end
70
+
71
+ def attributes_from_columns
72
+ @columns.collect do |col|
73
+ Rails::Generator::GeneratedAttribute.new col.name, col.type
74
+ end
75
+ end
76
+
77
+ def validate
78
+ @valid = !model.nil?
79
+ end
80
+
81
+ def banner
82
+ "script/generate view_for model [ --view view:view_parameter ]"
83
+ end
84
+
85
+ end
@@ -0,0 +1,88 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+
3
+ auto_complete_for :<%= controller_singular_name %>, :<%= auto_complete_attribute %>
4
+
5
+ # GET /<%= table_name %>
6
+ # GET /<%= table_name %>.xml
7
+ def index
8
+ @<%= table_name %> = <%= class_name %>.all
9
+
10
+ respond_to do |format|
11
+ format.html # index.html.erb
12
+ format.xml { render :xml => @<%= table_name %> }
13
+ end
14
+ end
15
+
16
+ # GET /<%= table_name %>/1
17
+ # GET /<%= table_name %>/1.xml
18
+ def show
19
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
20
+
21
+ respond_to do |format|
22
+ format.html # show.html.erb
23
+ format.xml { render :xml => @<%= file_name %> }
24
+ end
25
+ end
26
+
27
+ # GET /<%= table_name %>/new
28
+ # GET /<%= table_name %>/new.xml
29
+ def new
30
+ @<%= file_name %> = <%= class_name %>.new
31
+
32
+ respond_to do |format|
33
+ format.html # new.html.erb
34
+ format.xml { render :xml => @<%= file_name %> }
35
+ end
36
+ end
37
+
38
+ # GET /<%= table_name %>/1/edit
39
+ def edit
40
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
41
+ end
42
+
43
+ # POST /<%= table_name %>
44
+ # POST /<%= table_name %>.xml
45
+ def create
46
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
47
+
48
+ respond_to do |format|
49
+ if @<%= file_name %>.save
50
+ flash[:notice] = '<%= class_name %> was successfully created.'
51
+ format.html { redirect_to(@<%= file_name %>) }
52
+ format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
53
+ else
54
+ format.html { render :action => "new" }
55
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
56
+ end
57
+ end
58
+ end
59
+
60
+ # PUT /<%= table_name %>/1
61
+ # PUT /<%= table_name %>/1.xml
62
+ def update
63
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
64
+
65
+ respond_to do |format|
66
+ if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
67
+ flash[:notice] = '<%= class_name %> was successfully updated.'
68
+ format.html { redirect_to(@<%= file_name %>) }
69
+ format.xml { head :ok }
70
+ else
71
+ format.html { render :action => "edit" }
72
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
73
+ end
74
+ end
75
+ end
76
+
77
+ # DELETE /<%= table_name %>/1
78
+ # DELETE /<%= table_name %>/1.xml
79
+ def destroy
80
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
81
+ @<%= file_name %>.destroy
82
+
83
+ respond_to do |format|
84
+ format.html { redirect_to(<%= table_name %>_url) }
85
+ format.xml { head :ok }
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
4
+ test "should get index" do
5
+ get :index
6
+ assert_response :success
7
+ assert_not_nil assigns(:<%= table_name %>)
8
+ end
9
+
10
+ test "should get new" do
11
+ get :new
12
+ assert_response :success
13
+ end
14
+
15
+ test "should create <%= file_name %>" do
16
+ assert_difference('<%= class_name %>.count') do
17
+ post :create, :<%= file_name %> => { }
18
+ end
19
+
20
+ assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
21
+ end
22
+
23
+ test "should show <%= file_name %>" do
24
+ get :show, :id => <%= table_name %>(:one).to_param
25
+ assert_response :success
26
+ end
27
+
28
+ test "should get edit" do
29
+ get :edit, :id => <%= table_name %>(:one).to_param
30
+ assert_response :success
31
+ end
32
+
33
+ test "should update <%= file_name %>" do
34
+ put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => { }
35
+ assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
36
+ end
37
+
38
+ test "should destroy <%= file_name %>" do
39
+ assert_difference('<%= class_name %>.count', -1) do
40
+ delete :destroy, :id => <%= table_name %>(:one).to_param
41
+ end
42
+
43
+ assert_redirected_to <%= table_name %>_path
44
+ end
45
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class <%= controller_class_name %>HelperTest < ActionView::TestCase
4
+ end
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7
+ <title><%= controller_class_name %>: <%%= controller.action_name %></title>
8
+ <%%= stylesheet_link_tag 'scaffold' %>
9
+ <%%= javascript_include_tag :defaults %>
10
+ </head>
11
+ <body>
12
+
13
+ <p style="color: green"><%%= flash[:notice] %></p>
14
+
15
+ <%%= yield %>
16
+
17
+ </body>
18
+ </html>
@@ -0,0 +1,54 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ .fieldWithErrors {
20
+ padding: 2px;
21
+ background-color: red;
22
+ display: table;
23
+ }
24
+
25
+ #errorExplanation {
26
+ width: 400px;
27
+ border: 2px solid red;
28
+ padding: 7px;
29
+ padding-bottom: 12px;
30
+ margin-bottom: 20px;
31
+ background-color: #f0f0f0;
32
+ }
33
+
34
+ #errorExplanation h2 {
35
+ text-align: left;
36
+ font-weight: bold;
37
+ padding: 5px 5px 5px 15px;
38
+ font-size: 12px;
39
+ margin: -7px;
40
+ background-color: #c00;
41
+ color: #fff;
42
+ }
43
+
44
+ #errorExplanation p {
45
+ color: #333;
46
+ margin-bottom: 0;
47
+ padding: 5px;
48
+ }
49
+
50
+ #errorExplanation ul li {
51
+ font-size: 12px;
52
+ list-style: square;
53
+ }
54
+
@@ -0,0 +1,21 @@
1
+ <h1>Editing <%= singular_name %></h1>
2
+
3
+ <%% form_for(@<%= singular_name %>) do |f| %>
4
+ <%%= f.error_messages %>
5
+ <% for attribute in attributes -%>
6
+ <p>
7
+ <%%= f.label :<%= attribute.name %> %><br />
8
+ <%- if auto_complete_attribute == attribute.name -%>
9
+ <%%= text_field_with_auto_complete :<%= singular_name %>, :<%= attribute.name %>, {}, { :method => :get } %>
10
+ <%- else -%>
11
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
12
+ <%- end -%>
13
+ </p>
14
+ <% end -%>
15
+ <p>
16
+ <%%= f.submit 'Update' %>
17
+ </p>
18
+ <%% end %>
19
+
20
+ <%%= link_to 'Show', @<%= singular_name %> %> |
21
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,24 @@
1
+ <h1>Listing <%= plural_name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <% for attribute in attributes -%>
6
+ <th><%= attribute.column.human_name %></th>
7
+ <% end -%>
8
+ </tr>
9
+
10
+ <%% @<%= plural_name %>.each do |<%= singular_name %>| %>
11
+ <tr>
12
+ <% for attribute in attributes -%>
13
+ <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
14
+ <% end -%>
15
+ <td><%%= link_to 'Show', <%= singular_name %> %></td>
16
+ <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
17
+ <td><%%= link_to 'Destroy', <%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
18
+ </tr>
19
+ <%% end %>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%%= link_to 'New <%= singular_name %>', new_<%= singular_name %>_path %>
@@ -0,0 +1,20 @@
1
+ <h1>New <%= singular_name %></h1>
2
+
3
+ <%% form_for(@<%= singular_name %>) do |f| %>
4
+ <%%= f.error_messages %>
5
+ <%- for attribute in attributes -%>
6
+ <p>
7
+ <%%= f.label :<%= attribute.name %> %><br />
8
+ <%- if auto_complete_attribute == attribute.name -%>
9
+ <%%= text_field_with_auto_complete :<%= singular_name %>, :<%= attribute.name %>, {}, { :method => :get } %>
10
+ <%- else -%>
11
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
12
+ <%- end -%>
13
+ </p>
14
+ <%- end -%>
15
+ <p>
16
+ <%%= f.submit 'Create' %>
17
+ </p>
18
+ <%% end %>
19
+
20
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,10 @@
1
+ <% for attribute in attributes -%>
2
+ <p>
3
+ <b><%= attribute.column.human_name %>:</b>
4
+ <%%=h @<%= singular_name %>.<%= attribute.name %> %>
5
+ </p>
6
+
7
+ <% end -%>
8
+
9
+ <%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
10
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,44 @@
1
+ module ViewMapper
2
+ module AutoCompleteView
3
+
4
+ def source_root_for_view
5
+ File.dirname(__FILE__) + "/auto_complete_templates"
6
+ end
7
+
8
+ def manifest
9
+ manifest = super
10
+ if @valid
11
+ manifest.route :name => 'connect',
12
+ :path => auto_complete_for_method,
13
+ :controller => controller_file_name,
14
+ :action => auto_complete_for_method
15
+ end
16
+ manifest
17
+ end
18
+
19
+ def auto_complete_for_method
20
+ "auto_complete_for_#{singular_name}_#{auto_complete_attribute}"
21
+ end
22
+
23
+ def auto_complete_attribute
24
+ view_param
25
+ end
26
+
27
+ def validate
28
+ super
29
+ @valid &&= validate_auto_complete_attribute
30
+ end
31
+
32
+ def validate_auto_complete_attribute
33
+ if auto_complete_attribute.nil?
34
+ logger.error "No auto_complete attribute specified."
35
+ return false
36
+ elsif attributes.find { |a| a.name == auto_complete_attribute }.nil?
37
+ logger.error "Field '#{auto_complete_attribute}' does not exist."
38
+ return false
39
+ end
40
+ true
41
+ end
42
+
43
+ end
44
+ end