view_mapper 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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'