view_mapper 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.rdoc +3 -1
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/lib/view_mapper/belongs_to_parent_models.rb +130 -0
  5. data/lib/view_mapper/model_info.rb +2 -6
  6. data/lib/view_mapper/views/auto_complete/auto_complete_view.rb +2 -1
  7. data/lib/view_mapper/views/belongs_to/belongs_to_view.rb +1 -86
  8. data/lib/view_mapper/views/belongs_to/templates/{model.rb → model.erb} +2 -2
  9. data/lib/view_mapper/views/belongs_to/templates/view_form.html.erb +1 -1
  10. data/lib/view_mapper/views/belongs_to/templates/view_index.html.erb +1 -1
  11. data/lib/view_mapper/views/belongs_to/templates/view_show.html.erb +1 -1
  12. data/lib/view_mapper/views/belongs_to_auto_complete/belongs_to_auto_complete_view.rb +60 -0
  13. data/lib/view_mapper/views/belongs_to_auto_complete/templates/controller.rb +90 -0
  14. data/lib/view_mapper/views/belongs_to_auto_complete/templates/layout.html.erb +18 -0
  15. data/lib/view_mapper/views/belongs_to_auto_complete/templates/migration.rb +19 -0
  16. data/lib/view_mapper/views/belongs_to_auto_complete/templates/model.erb +16 -0
  17. data/lib/view_mapper/views/belongs_to_auto_complete/templates/view_edit.html.erb +11 -0
  18. data/lib/view_mapper/views/belongs_to_auto_complete/templates/view_form.html.erb +13 -0
  19. data/lib/view_mapper/views/belongs_to_auto_complete/templates/view_index.html.erb +30 -0
  20. data/lib/view_mapper/views/belongs_to_auto_complete/templates/view_new.html.erb +10 -0
  21. data/lib/view_mapper/views/belongs_to_auto_complete/templates/view_show.html.erb +16 -0
  22. data/lib/view_mapper/views/paperclip/paperclip_view.rb +2 -1
  23. data/lib/view_mapper.rb +2 -0
  24. data/test/test_helper.rb +29 -7
  25. data/test/views/auto_complete/auto_complete_test.rb +1 -1
  26. data/test/views/belongs_to/belongs_to_test.rb +13 -10
  27. data/test/views/belongs_to/expected_templates/_form.html.erb +1 -1
  28. data/test/views/belongs_to/expected_templates/index.html.erb +1 -1
  29. data/test/views/belongs_to/expected_templates/show.html.erb +1 -1
  30. data/test/views/belongs_to/expected_templates/some_other_model.rb +2 -2
  31. data/test/views/belongs_to_auto_complete/belongs_to_auto_complete_test.rb +489 -0
  32. data/test/views/belongs_to_auto_complete/expected_templates/_form.html.erb +13 -0
  33. data/test/views/belongs_to_auto_complete/expected_templates/create_some_other_models.rb +18 -0
  34. data/test/views/belongs_to_auto_complete/expected_templates/edit.html.erb +11 -0
  35. data/test/views/belongs_to_auto_complete/expected_templates/expected_routes.rb +47 -0
  36. data/test/views/belongs_to_auto_complete/expected_templates/index.html.erb +24 -0
  37. data/test/views/belongs_to_auto_complete/expected_templates/new.html.erb +10 -0
  38. data/test/views/belongs_to_auto_complete/expected_templates/show.html.erb +17 -0
  39. data/test/views/belongs_to_auto_complete/expected_templates/some_other_model.rb +16 -0
  40. data/test/views/belongs_to_auto_complete/expected_templates/some_other_models.html.erb +18 -0
  41. data/test/views/belongs_to_auto_complete/expected_templates/some_other_models_controller.rb +89 -0
  42. data/test/views/belongs_to_auto_complete/expected_templates/standard_routes.rb +43 -0
  43. data/view_mapper.gemspec +35 -6
  44. metadata +33 -4
data/README.rdoc CHANGED
@@ -43,7 +43,9 @@ This is the same as view_for, but will also generate a new model at the same tim
43
43
 
44
44
  {has_many_auto_complete}[http://patshaughnessy.net/2009/11/25/scaffolding-for-auto-complete-on-a-complex-nested-form]: This is the same as "has_many" but also uses the auto_complete plugin to implement type ahead behavior for each text field. This view requires you to install the {repeated_auto_complete}[http://patshaughnessy.net/repeated_auto_complete] plugin.
45
45
 
46
- {belongs_to}: Generates scaffolding that allows you to select an existing, associated model.
46
+ {belongs_to}[http://patshaughnessy.net/2010/1/25/creating-associations-to-existing-data-part-1-belongs_to-scaffolding]: Generates scaffolding that allows you to select an existing, associated model.
47
+
48
+ belongs_to_auto_complete: Generates scaffolding that allows you to select an existing, associated model using auto_complete.
47
49
 
48
50
  == Examples
49
51
 
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gem.email = "pat@patshaughnessy.net"
11
11
  gem.homepage = "http://patshaughnessy.net/view_mapper"
12
12
  gem.authors = ["Pat Shaughnessy"]
13
- gem.add_development_dependency "thoughtbot-shoulda"
13
+ gem.add_development_dependency "shoulda"
14
14
  gem.add_development_dependency "mocha"
15
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
16
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.3.3
@@ -0,0 +1,130 @@
1
+ module ViewMapper
2
+ module BelongsToParentModels
3
+
4
+ def manifest
5
+ m = super.edit do |action|
6
+ action unless is_model_dependency_action(action) || !valid
7
+ end
8
+ if valid
9
+ m.template(
10
+ "view_form.html.erb",
11
+ File.join('app/views', controller_class_path, controller_file_name, "_form.html.erb")
12
+ )
13
+ add_model_actions(m) unless view_only?
14
+ end
15
+ m
16
+ end
17
+
18
+ def add_model_actions(m)
19
+ m.directory(File.join('test/fixtures', class_path))
20
+ m.template 'model.erb', File.join('app/models', class_path, "#{file_name}.rb")
21
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
22
+ unless options[:skip_fixture]
23
+ m.template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
24
+ end
25
+ unless options[:skip_migration]
26
+ m.migration_template 'migration.rb',
27
+ 'db/migrate',
28
+ :assigns => { :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" },
29
+ :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
30
+ end
31
+ end
32
+
33
+ def is_model_dependency_action(action)
34
+ action[0] == :dependency && action[1].include?('model')
35
+ end
36
+
37
+ def parent_models
38
+ @parent_models ||= find_parent_models
39
+ end
40
+
41
+ def find_parent_models
42
+ if view_param
43
+ view_param.split(',').collect do |param|
44
+ model_info_from_param(param)
45
+ end
46
+ elsif view_only?
47
+ model.parent_models
48
+ else
49
+ []
50
+ end
51
+ end
52
+
53
+ def model_info_from_param(param)
54
+ if /(.*)\[(.*)\]/.match(param)
55
+ parent_model = ModelInfo.new($1.singularize)
56
+ select_parent_by parent_model, $2
57
+ else
58
+ parent_model = ModelInfo.new(param.singularize)
59
+ end
60
+ parent_model
61
+ end
62
+
63
+ def validate_parent_models
64
+ parents = parent_models
65
+ if parents.empty?
66
+ if view_only?
67
+ logger.error "No belongs_to associations exist in class #{model.name}."
68
+ else
69
+ logger.error "No belongs_to association specified."
70
+ end
71
+ return false
72
+ end
73
+ parents.reject! { |parent_model| !validate_parent_model(parent_model) }
74
+ @parent_models = parents
75
+ !parents.empty?
76
+ end
77
+
78
+ def validate_parent_model(parent_model)
79
+ parent_model_name = parent_model.name
80
+ if !parent_model.valid?
81
+ logger.error parent_model.error
82
+ return false
83
+ elsif view_only? && !model.belongs_to?(parent_model_name)
84
+ logger.warning "Model #{model.name} does not belong to model #{parent_model_name}."
85
+ return false
86
+ elsif view_only? && !model.has_method?(virtual_attribute_for(parent_model))
87
+ logger.warning "Model #{model.name} does not have a method #{virtual_attribute_for(parent_model)}."
88
+ return false
89
+ elsif view_only? && !model.has_method?(virtual_attribute_setter_for(parent_model))
90
+ logger.warning "Model #{model.name} does not have a method #{virtual_attribute_setter_for(parent_model)}."
91
+ return false
92
+ elsif view_only? && !model.has_foreign_key_for?(parent_model_name)
93
+ logger.warning "Model #{class_name} does not contain a foreign key for #{parent_model_name}."
94
+ return false
95
+ elsif !parent_model.has_many?(class_name.pluralize)
96
+ logger.warning "Model #{parent_model_name} does not contain a has_many association for #{class_name}."
97
+ return false
98
+ elsif !parent_model.has_method?(field_for(parent_model)) && !parent_model.has_column?(field_for(parent_model))
99
+ logger.warning "Model #{parent_model_name} does not have a #{field_for(parent_model)} attribute."
100
+ return false
101
+ end
102
+ true
103
+ end
104
+
105
+ def field_for(parent_model)
106
+ name = parent_fields[parent_model.name]
107
+ name ? name : 'name'
108
+ end
109
+
110
+ def virtual_attribute_for(parent_model)
111
+ "#{parent_model.name.underscore}_#{field_for(parent_model)}"
112
+ end
113
+
114
+ def virtual_attribute_setter_for(parent_model)
115
+ "#{virtual_attribute_for(parent_model)}="
116
+ end
117
+
118
+ private
119
+
120
+ def select_parent_by(parent_model, field)
121
+ parent_fields[parent_model.name] = field
122
+ end
123
+
124
+ def parent_fields
125
+ @parent_fields ||= {}
126
+ end
127
+
128
+ end
129
+ end
130
+
@@ -24,7 +24,7 @@ module ViewMapper
24
24
  end
25
25
 
26
26
  def has_method?(method_name)
27
- model.new.methods.include?(method_name)
27
+ model.new.methods.include?(method_name) || model.new.methods.include?(method_name.to_sym)
28
28
  end
29
29
 
30
30
  def attributes
@@ -68,7 +68,7 @@ module ViewMapper
68
68
  end
69
69
 
70
70
  def accepts_nested_attributes_for?(child_model)
71
- if !model.new.methods.include? "#{child_model.name.underscore.pluralize}_attributes="
71
+ if !has_method?("#{child_model.name.underscore.pluralize}_attributes=")
72
72
  @error = "Model #{model} does not accept nested attributes for model #{child_model.name}."
73
73
  false
74
74
  else
@@ -92,10 +92,6 @@ module ViewMapper
92
92
  model.columns.detect { |col| is_foreign_key_for?(col, parent_model_name) }
93
93
  end
94
94
 
95
- def has_virtual_name_method?(parent_model_name)
96
- model.new.methods.include? "#{parent_model_name.underscore}_name"
97
- end
98
-
99
95
  private
100
96
 
101
97
  def find_model(model_name)
@@ -70,7 +70,8 @@ module ViewMapper
70
70
  end
71
71
 
72
72
  def auto_complete_installed
73
- ActionController::Base.methods.include? 'auto_complete_for'
73
+ ActionController::Base.methods.include?('auto_complete_for') ||
74
+ ActionController::Base.methods.include?(:auto_complete_for)
74
75
  end
75
76
 
76
77
  end
@@ -1,7 +1,7 @@
1
1
  module ViewMapper
2
2
  module BelongsToView
3
3
 
4
- attr_reader :parent_models
4
+ include BelongsToParentModels
5
5
 
6
6
  def self.source_root
7
7
  File.expand_path(File.dirname(__FILE__) + "/templates")
@@ -11,95 +11,10 @@ module ViewMapper
11
11
  [ BelongsToView.source_root, File.expand_path(source_root), File.join(self.class.lookup('model').path, 'templates') ]
12
12
  end
13
13
 
14
- def manifest
15
- m = super.edit do |action|
16
- action unless is_model_dependency_action(action) || !valid
17
- end
18
- if valid
19
- m.template(
20
- "view_form.html.erb",
21
- File.join('app/views', controller_class_path, controller_file_name, "_form.html.erb")
22
- )
23
- add_model_actions(m) unless view_only?
24
- end
25
- m
26
- end
27
-
28
- def add_model_actions(m)
29
- m.directory(File.join('test/fixtures', class_path))
30
- m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
31
- m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
32
- unless options[:skip_fixture]
33
- m.template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
34
- end
35
- unless options[:skip_migration]
36
- m.migration_template 'migration.rb',
37
- 'db/migrate',
38
- :assigns => { :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" },
39
- :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
40
- end
41
- end
42
-
43
- def is_model_dependency_action(action)
44
- action[0] == :dependency && action[1].include?('model')
45
- end
46
-
47
- def parent_models
48
- @parent_models ||= find_parent_models
49
- end
50
-
51
- def find_parent_models
52
- if view_param
53
- view_param.split(',').collect { |param| ModelInfo.new(param.singularize) }
54
- elsif view_only?
55
- model.parent_models
56
- else
57
- []
58
- end
59
- end
60
-
61
14
  def validate
62
15
  super
63
16
  @valid &&= validate_parent_models
64
17
  end
65
18
 
66
- def validate_parent_models
67
- parents = parent_models
68
- if parents.empty?
69
- if view_only?
70
- logger.error "No belongs_to associations exist in class #{model.name}."
71
- else
72
- logger.error "No belongs_to association specified."
73
- end
74
- return false
75
- end
76
- parents.reject! { |parent_model| !validate_parent_model(parent_model) }
77
- @parent_models = parents
78
- !parents.empty?
79
- end
80
-
81
- def validate_parent_model(parent_model)
82
- if !parent_model.valid?
83
- logger.error parent_model.error
84
- return false
85
- elsif view_only? && !model.belongs_to?(parent_model.name)
86
- logger.warning "Model #{model.name} does not belong to model #{parent_model.name}."
87
- return false
88
- elsif view_only? && !model.has_virtual_name_method?(parent_model.name)
89
- logger.warning "Model #{model.name} does not have a method #{parent_model.name.underscore}_name."
90
- return false
91
- elsif view_only? && !model.has_foreign_key_for?(parent_model.name)
92
- logger.warning "Model #{class_name} does not contain a foreign key for #{parent_model.name}."
93
- return false
94
- elsif !parent_model.has_many?(class_name.pluralize)
95
- logger.warning "Model #{parent_model.name} does not contain a has_many association for #{class_name}."
96
- return false
97
- elsif !parent_model.has_column?('name') && !parent_model.has_method?('name')
98
- logger.warning "Model #{parent_model.name} does not have a name attribute."
99
- return false
100
- end
101
- true
102
- end
103
-
104
19
  end
105
20
  end
@@ -6,8 +6,8 @@ class <%= class_name %> < ActiveRecord::Base
6
6
  belongs_to :<%= parent_model.name.underscore %>
7
7
  <% end -%>
8
8
  <% for parent_model in parent_models -%>
9
- def <%= parent_model.name.underscore %>_name
10
- <%= parent_model.name.underscore %>.name if <%= parent_model.name.underscore %>
9
+ def <%= parent_model.name.underscore %>_<%= field_for(parent_model) %>
10
+ <%= parent_model.name.underscore %>.<%= field_for(parent_model) %> if <%= parent_model.name.underscore %>
11
11
  end
12
12
  <% end -%>
13
13
  end
@@ -8,6 +8,6 @@
8
8
  <% for parent_model in parent_models -%>
9
9
  <p>
10
10
  <%= parent_model.name.titleize %>:<br />
11
- <%%= f.collection_select(:<%= parent_model.name.underscore %>_id, <%= parent_model.name %>.all, :id, :name, { :prompt => true }) %>
11
+ <%%= f.collection_select(:<%= parent_model.name.underscore %>_id, <%= parent_model.name %>.all, :id, :<%= field_for(parent_model) %>, { :prompt => true }) %>
12
12
  </p>
13
13
  <% end -%>
@@ -16,7 +16,7 @@
16
16
  <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
17
17
  <% end -%>
18
18
  <% for parent_model in parent_models -%>
19
- <td><%%=h <%= singular_name %>.<%= parent_model.name.underscore %>_name %></td>
19
+ <td><%%=h <%= singular_name %>.<%= parent_model.name.underscore %>_<%= field_for(parent_model) %> %></td>
20
20
  <% end -%>
21
21
  <td><%%= link_to 'Show', <%= singular_name %> %></td>
22
22
  <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
@@ -8,7 +8,7 @@
8
8
  <% for parent_model in parent_models -%>
9
9
  <p>
10
10
  <b><%= parent_model.name.titleize %>:</b>
11
- <%%=h @<%= singular_name %>.<%= parent_model.name.underscore %>_name %>
11
+ <%%=h @<%= singular_name %>.<%= parent_model.name.underscore %>_<%= field_for(parent_model) %> %>
12
12
  </p>
13
13
 
14
14
  <% end -%>
@@ -0,0 +1,60 @@
1
+ module ViewMapper
2
+ module BelongsToAutoCompleteView
3
+
4
+ include BelongsToParentModels
5
+
6
+ def self.source_root
7
+ File.expand_path(File.dirname(__FILE__) + "/templates")
8
+ end
9
+
10
+ def source_roots_for_view
11
+ [ BelongsToAutoCompleteView.source_root, File.expand_path(source_root), File.join(self.class.lookup('model').path, 'templates') ]
12
+ end
13
+
14
+ def manifest
15
+ m = super
16
+ if valid
17
+ parent_models.reverse.each do |parent_model|
18
+ m.route :name => 'connect',
19
+ :path => auto_complete_for_method(parent_model),
20
+ :controller => controller_file_name,
21
+ :action => auto_complete_for_method(parent_model)
22
+ end
23
+ end
24
+ m
25
+ end
26
+
27
+ def auto_complete_for_method(parent_model)
28
+ "auto_complete_for_#{parent_model.name.underscore}_#{field_for(parent_model)}"
29
+ end
30
+
31
+ def validate
32
+ @valid = validate_auto_complete_installed
33
+ @valid &&= super
34
+ @valid &&= validate_parent_models
35
+ end
36
+
37
+ def validate_parent_model(parent_model)
38
+ valid = super
39
+ if valid && !parent_model.has_column?(field_for(parent_model))
40
+ logger.warning "Model #{parent_model.name} does not have a #{field_for(parent_model)} column."
41
+ return false
42
+ end
43
+ valid
44
+ end
45
+
46
+ def validate_auto_complete_installed
47
+ if !auto_complete_installed
48
+ logger.error "The auto_complete plugin does not appear to be installed."
49
+ return false
50
+ end
51
+ true
52
+ end
53
+
54
+ def auto_complete_installed
55
+ ActionController::Base.methods.include?('auto_complete_for') ||
56
+ ActionController::Base.methods.include?(:auto_complete_for)
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,90 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+
3
+ <% parent_models.each do |parent_model| -%>
4
+ auto_complete_for :<%= parent_model.name.underscore %>, :<%= field_for(parent_model) %>
5
+ <% end -%>
6
+
7
+ # GET /<%= table_name %>
8
+ # GET /<%= table_name %>.xml
9
+ def index
10
+ @<%= table_name %> = <%= class_name %>.all
11
+
12
+ respond_to do |format|
13
+ format.html # index.html.erb
14
+ format.xml { render :xml => @<%= table_name %> }
15
+ end
16
+ end
17
+
18
+ # GET /<%= table_name %>/1
19
+ # GET /<%= table_name %>/1.xml
20
+ def show
21
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
22
+
23
+ respond_to do |format|
24
+ format.html # show.html.erb
25
+ format.xml { render :xml => @<%= file_name %> }
26
+ end
27
+ end
28
+
29
+ # GET /<%= table_name %>/new
30
+ # GET /<%= table_name %>/new.xml
31
+ def new
32
+ @<%= file_name %> = <%= class_name %>.new
33
+
34
+ respond_to do |format|
35
+ format.html # new.html.erb
36
+ format.xml { render :xml => @<%= file_name %> }
37
+ end
38
+ end
39
+
40
+ # GET /<%= table_name %>/1/edit
41
+ def edit
42
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
43
+ end
44
+
45
+ # POST /<%= table_name %>
46
+ # POST /<%= table_name %>.xml
47
+ def create
48
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
49
+
50
+ respond_to do |format|
51
+ if @<%= file_name %>.save
52
+ flash[:notice] = '<%= class_name %> was successfully created.'
53
+ format.html { redirect_to(@<%= file_name %>) }
54
+ format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
55
+ else
56
+ format.html { render :action => "new" }
57
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
58
+ end
59
+ end
60
+ end
61
+
62
+ # PUT /<%= table_name %>/1
63
+ # PUT /<%= table_name %>/1.xml
64
+ def update
65
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
66
+
67
+ respond_to do |format|
68
+ if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
69
+ flash[:notice] = '<%= class_name %> was successfully updated.'
70
+ format.html { redirect_to(@<%= file_name %>) }
71
+ format.xml { head :ok }
72
+ else
73
+ format.html { render :action => "edit" }
74
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
75
+ end
76
+ end
77
+ end
78
+
79
+ # DELETE /<%= table_name %>/1
80
+ # DELETE /<%= table_name %>/1.xml
81
+ def destroy
82
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
83
+ @<%= file_name %>.destroy
84
+
85
+ respond_to do |format|
86
+ format.html { redirect_to(<%= table_name %>_url) }
87
+ format.xml { head :ok }
88
+ end
89
+ end
90
+ 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,19 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% for attribute in attributes -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+ <% for parent_model in parent_models -%>
8
+ t.integer :<%= parent_model.name.underscore %>_id
9
+ <% end -%>
10
+ <% unless options[:skip_timestamps] %>
11
+ t.timestamps
12
+ <% end -%>
13
+ end
14
+ end
15
+
16
+ def self.down
17
+ drop_table :<%= table_name %>
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ class <%= class_name %> < ActiveRecord::Base
2
+ <% attributes.select(&:reference?).each do |attribute| -%>
3
+ belongs_to :<%= attribute.name %>
4
+ <% end -%>
5
+ <% for parent_model in parent_models -%>
6
+ belongs_to :<%= parent_model.name.underscore %>
7
+ <% end -%>
8
+ <% for parent_model in parent_models -%>
9
+ def <%= parent_model.name.underscore %>_<%= field_for(parent_model) %>
10
+ <%= parent_model.name.underscore %>.<%= field_for(parent_model) %> if <%= parent_model.name.underscore %>
11
+ end
12
+ def <%= parent_model.name.underscore %>_<%= field_for(parent_model) %>=(<%= field_for(parent_model) %>)
13
+ self.<%= parent_model.name.underscore %> = <%= parent_model.name %>.find_by_<%= field_for(parent_model) %>(<%= field_for(parent_model) %>)
14
+ end
15
+ <% end -%>
16
+ end
@@ -0,0 +1,11 @@
1
+ <h1>Editing <%= singular_name %></h1>
2
+
3
+ <%% form_for(@<%= singular_name %>) do |f| %>
4
+ <%%= render :partial => 'form', :locals => { :f => f } %>
5
+ <p>
6
+ <%%= f.submit 'Update' %>
7
+ </p>
8
+ <%% end %>
9
+
10
+ <%%= link_to 'Show', @<%= singular_name %> %> |
11
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,13 @@
1
+ <%%= f.error_messages %>
2
+ <% for attribute in attributes -%>
3
+ <p>
4
+ <%%= f.label :<%= attribute.name %> %><br />
5
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
6
+ </p>
7
+ <%- end -%>
8
+ <% for parent_model in parent_models -%>
9
+ <p>
10
+ <%= parent_model.name.titleize %>:<br />
11
+ <%%= text_field_with_auto_complete :<%= singular_name %>, :<%= parent_model.name.underscore %>_<%= field_for(parent_model) %>, {}, { :method => :get, :url => '/auto_complete_for_<%= parent_model.name.underscore %>_<%= field_for(parent_model) %>', :param_name => '<%= parent_model.name.underscore %>[<%= field_for(parent_model) %>]' } %>
12
+ </p>
13
+ <% end -%>
@@ -0,0 +1,30 @@
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
+ <% for parent_model in parent_models -%>
9
+ <th><%= parent_model.name.titleize %></th>
10
+ <% end -%>
11
+ </tr>
12
+
13
+ <%% @<%= plural_name %>.each do |<%= singular_name %>| %>
14
+ <tr>
15
+ <% for attribute in attributes -%>
16
+ <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
17
+ <% end -%>
18
+ <% for parent_model in parent_models -%>
19
+ <td><%%=h <%= singular_name %>.<%= parent_model.name.underscore %>_<%= field_for(parent_model) %> %></td>
20
+ <% end -%>
21
+ <td><%%= link_to 'Show', <%= singular_name %> %></td>
22
+ <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
23
+ <td><%%= link_to 'Destroy', <%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
24
+ </tr>
25
+ <%% end %>
26
+ </table>
27
+
28
+ <br />
29
+
30
+ <%%= link_to 'New <%= singular_name %>', new_<%= singular_name %>_path %>
@@ -0,0 +1,10 @@
1
+ <h1>New <%= singular_name %></h1>
2
+
3
+ <%% form_for(@<%= singular_name %>) do |f| %>
4
+ <%%= render :partial => 'form', :locals => { :f => f } %>
5
+ <p>
6
+ <%%= f.submit 'Create' %>
7
+ </p>
8
+ <%% end %>
9
+
10
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,16 @@
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
+ <% for parent_model in parent_models -%>
9
+ <p>
10
+ <b><%= parent_model.name.titleize %>:</b>
11
+ <%%=h @<%= singular_name %>.<%= parent_model.name.underscore %>_<%= field_for(parent_model) %> %>
12
+ </p>
13
+
14
+ <% end -%>
15
+ <%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
16
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -87,7 +87,8 @@ module ViewMapper
87
87
  end
88
88
 
89
89
  def paperclip_installed
90
- ActiveRecord::Base.methods.include? 'has_attached_file'
90
+ ActiveRecord::Base.methods.include?('has_attached_file') ||
91
+ ActiveRecord::Base.methods.include?(:has_attached_file)
91
92
  end
92
93
 
93
94
  end
data/lib/view_mapper.rb CHANGED
@@ -2,8 +2,10 @@ require 'view_mapper/route_action'
2
2
  require 'view_mapper/editable_manifest'
3
3
  require 'view_mapper/model_info'
4
4
  require 'view_mapper/has_many_child_models'
5
+ require 'view_mapper/belongs_to_parent_models'
5
6
  require 'view_mapper/view_mapper'
6
7
  require 'view_mapper/views/auto_complete/auto_complete_view'
7
8
  require 'view_mapper/views/paperclip/paperclip_view'
8
9
  require 'view_mapper/views/has_many/has_many_view'
9
10
  require 'view_mapper/views/belongs_to/belongs_to_view'
11
+ require 'view_mapper/views/belongs_to_auto_complete/belongs_to_auto_complete_view'