view_mapper 0.3.1 → 0.3.2

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.
data/README.rdoc CHANGED
@@ -41,6 +41,10 @@ This is the same as view_for, but will also generate a new model at the same tim
41
41
 
42
42
  {has_many}[http://patshaughnessy.net/2009/11/9/scaffolding-for-complex-forms-using-nested-attributes]: Generates scaffolding for a complex form to edit two or more associated models.
43
43
 
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
+
46
+ {belongs_to}: Generates scaffolding that allows you to select an existing, associated model.
47
+
44
48
  == Examples
45
49
 
46
50
  For detailed examples and more information see: http://patshaughnessy.net/view_mapper
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.3.2
@@ -19,6 +19,14 @@ module ViewMapper
19
19
  @columns ||= active_record_columns.collect { |col| col.name }
20
20
  end
21
21
 
22
+ def has_column?(col_name)
23
+ model.column_names.include? col_name
24
+ end
25
+
26
+ def has_method?(method_name)
27
+ model.new.methods.include?(method_name)
28
+ end
29
+
22
30
  def attributes
23
31
  @attributes ||= active_record_columns.collect { |col| Rails::Generator::GeneratedAttribute.new col.name, col.type }
24
32
  end
@@ -44,7 +52,15 @@ module ViewMapper
44
52
  end
45
53
 
46
54
  def child_models
47
- model.reflections.select { |key, value| value.macro == :has_many }.collect do |kvpair|
55
+ model_info_array_for_association(:has_many)
56
+ end
57
+
58
+ def parent_models
59
+ model_info_array_for_association(:belongs_to)
60
+ end
61
+
62
+ def model_info_array_for_association(association_type)
63
+ model.reflections.select { |key, value| value.macro == association_type }.collect do |kvpair|
48
64
  kvpair[0].to_s.singularize
49
65
  end.sort.collect do |model_name|
50
66
  ModelInfo.new model_name
@@ -76,6 +92,10 @@ module ViewMapper
76
92
  model.columns.detect { |col| is_foreign_key_for?(col, parent_model_name) }
77
93
  end
78
94
 
95
+ def has_virtual_name_method?(parent_model_name)
96
+ model.new.methods.include? "#{parent_model_name.underscore}_name"
97
+ end
98
+
79
99
  private
80
100
 
81
101
  def find_model(model_name)
@@ -0,0 +1,105 @@
1
+ module ViewMapper
2
+ module BelongsToView
3
+
4
+ attr_reader :parent_models
5
+
6
+ def self.source_root
7
+ File.expand_path(File.dirname(__FILE__) + "/templates")
8
+ end
9
+
10
+ def source_roots_for_view
11
+ [ BelongsToView.source_root, File.expand_path(source_root), File.join(self.class.lookup('model').path, 'templates') ]
12
+ end
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
+ def validate
62
+ super
63
+ @valid &&= validate_parent_models
64
+ end
65
+
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
+ end
105
+ end
@@ -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,13 @@
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 %>_name
10
+ <%= parent_model.name.underscore %>.name if <%= parent_model.name.underscore %>
11
+ end
12
+ <% end -%>
13
+ 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
+ <%%= f.collection_select(:<%= parent_model.name.underscore %>_id, <%= parent_model.name %>.all, :id, :name, { :prompt => true }) %>
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 %>_name %></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 %>_name %>
12
+ </p>
13
+
14
+ <% end -%>
15
+ <%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
16
+ <%%= link_to 'Back', <%= plural_name %>_path %>
data/lib/view_mapper.rb CHANGED
@@ -6,3 +6,4 @@ require 'view_mapper/view_mapper'
6
6
  require 'view_mapper/views/auto_complete/auto_complete_view'
7
7
  require 'view_mapper/views/paperclip/paperclip_view'
8
8
  require 'view_mapper/views/has_many/has_many_view'
9
+ require 'view_mapper/views/belongs_to/belongs_to_view'
data/test/test_helper.rb CHANGED
@@ -3,7 +3,7 @@ require 'rubygems'
3
3
  require 'test/unit'
4
4
  require 'shoulda'
5
5
  require 'mocha'
6
- require 'activerecord'
6
+ require 'active_record'
7
7
 
8
8
  ActiveRecord::Base.establish_connection({ :adapter => 'sqlite3', :database => ':memory:' })
9
9
 
@@ -54,7 +54,7 @@ def setup_test_model(paperclip_columns = false)
54
54
  Object.const_get("Testy")
55
55
  end
56
56
 
57
- def setup_parent_test_model(create_foreign_key = true, child_belongs_to_parent = true)
57
+ def setup_parent_test_model(create_foreign_key = true, child_belongs_to_parent = true, parent_has_many_children = true)
58
58
  ActiveRecord::Base.connection.create_table :parents, :force => true do |table|
59
59
  table.column :name, :string
60
60
  end
@@ -69,7 +69,7 @@ def setup_parent_test_model(create_foreign_key = true, child_belongs_to_parent =
69
69
  Object.const_set("SomeOtherModel", Class.new(ActiveRecord::Base))
70
70
  Parent.class_eval do
71
71
  has_many :testies
72
- has_many :some_other_model
72
+ has_many :some_other_models unless !parent_has_many_children
73
73
  def testies_attributes=
74
74
  'fake'
75
75
  end
@@ -82,10 +82,38 @@ def setup_parent_test_model(create_foreign_key = true, child_belongs_to_parent =
82
82
  end
83
83
  SomeOtherModel.class_eval do
84
84
  belongs_to :parent
85
+ def parent_name
86
+ 'something'
87
+ end
85
88
  end
86
89
  Object.const_get("Parent")
87
90
  end
88
91
 
92
+ def setup_second_parent_test_model(has_name_virtual_attribute = true, has_foreign_key = true, parent_has_name_method = false, parent_has_name_column = true)
93
+ ActiveRecord::Base.connection.create_table :second_parents, :force => true do |table|
94
+ table.column :name, :string unless !parent_has_name_column
95
+ table.column :other_field, :string
96
+ end
97
+ ActiveRecord::Base.connection.add_column :some_other_models, :second_parent_id, :integer unless !has_foreign_key
98
+ Object.send(:remove_const, "SecondParent") rescue nil
99
+ Object.const_set("SecondParent", Class.new(ActiveRecord::Base))
100
+ SecondParent.class_eval do
101
+ has_many :some_other_models
102
+ def some_other_models_attributes=
103
+ 'fake'
104
+ end
105
+ def name
106
+ 'fake'
107
+ end unless !parent_has_name_method
108
+ end
109
+ SomeOtherModel.class_eval do
110
+ belongs_to :second_parent
111
+ def second_parent_name
112
+ 'something'
113
+ end unless !has_name_virtual_attribute
114
+ end
115
+ end
116
+
89
117
  def setup_test_model_without_nested_attributes
90
118
  ActiveRecord::Base.connection.create_table :third_models, :force => true do |table|
91
119
  table.column :name, :string
@@ -13,17 +13,17 @@ class ViewMapperTest < Test::Unit::TestCase
13
13
 
14
14
  should "have the proper default value for source_roots_for_view" do
15
15
  assert_equal [
16
- '/Users/pat/rails-apps/view_mapper/test/views/fake/templates',
17
- '/Users/pat/rails-apps/view_mapper/test/generators/fake/templates'
16
+ File.expand_path(File.dirname(__FILE__) + '/views/fake/templates'),
17
+ File.expand_path(File.dirname(__FILE__) + '/generators/fake/templates')
18
18
  ], @gen.source_roots_for_view
19
19
  end
20
20
 
21
21
  should "use the correct source path for a template file that is overridden in the view" do
22
- assert_equal '/Users/pat/rails-apps/view_mapper/test/views/fake/templates/fake_template1.html.erb', @gen.source_path('fake_template1.html.erb')
22
+ assert_equal File.expand_path(File.dirname(__FILE__) + '/views/fake/templates/fake_template1.html.erb'), @gen.source_path('fake_template1.html.erb')
23
23
  end
24
24
 
25
25
  should "use the correct source path for a template file that is not overridden in the view" do
26
- assert_equal '/Users/pat/rails-apps/view_mapper/test/generators/fake/templates/fake_template2.html.erb', @gen.source_path('fake_template2.html.erb')
26
+ assert_equal File.expand_path(File.dirname(__FILE__) + '/generators/fake/templates/fake_template2.html.erb'), @gen.source_path('fake_template2.html.erb')
27
27
  end
28
28
  end
29
29
 
@@ -0,0 +1,348 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class BelongsToViewTest < Test::Unit::TestCase
4
+
5
+ attr_reader :singular_name
6
+ attr_reader :attributes
7
+ attr_reader :plural_name
8
+ attr_reader :parent_models
9
+ attr_reader :class_name
10
+ attr_reader :migration_name
11
+ attr_reader :table_name
12
+ attr_reader :options
13
+
14
+ context "A view_for generator instantiated for a test model" do
15
+ setup do
16
+ setup_test_model
17
+ setup_parent_test_model
18
+ end
19
+
20
+ should "detect the existing parents when no parent is specified" do
21
+ gen = new_generator_for_test_model('view_for', ['--view', 'belongs_to'], 'some_other_model')
22
+ parent_models = gen.parent_models
23
+ assert_equal 1, parent_models.size
24
+ assert_equal 'Parent', parent_models[0].name
25
+ end
26
+
27
+ should "use the specified parent if provided" do
28
+ gen = new_generator_for_test_model('view_for', ['--view', 'belongs_to:parent'], 'some_other_model')
29
+ parent_models = gen.parent_models
30
+ assert_equal 1, parent_models.size
31
+ assert_equal 'Parent', parent_models[0].name
32
+ end
33
+
34
+ should "return an error message with a bad parent param" do
35
+ Rails::Generator::Base.logger.expects('error').with('Class \'blah\' does not exist or contains a syntax error and could not be loaded.')
36
+ new_generator_for_test_model('view_for', ['--view', 'belongs_to:blah'])
37
+ end
38
+ end
39
+
40
+ context "A scaffold_for_view generator instantiated for a test model" do
41
+ setup do
42
+ setup_test_model
43
+ setup_parent_test_model
44
+ end
45
+
46
+ should "return a warning when run with scaffold_for_view when no belongs_to is specified and not run any actions" do
47
+ expect_no_actions
48
+ Rails::Generator::Base.logger.expects('error').with('No belongs_to association specified.')
49
+ @generator_script = Rails::Generator::Scripts::Generate.new
50
+ @generator_script.run(generator_script_cmd_line('scaffold_for_view', ['--view', 'belongs_to']))
51
+ end
52
+ end
53
+
54
+ context "A test model with no belongs_to associations" do
55
+ setup do
56
+ setup_test_model
57
+ setup_parent_test_model(true, false)
58
+ end
59
+
60
+ should "return a error when run with view_for and not run any actions" do
61
+ expect_no_actions
62
+ Rails::Generator::Base.logger.expects('error').with('No belongs_to associations exist in class Testy.')
63
+ @generator_script = Rails::Generator::Scripts::Generate.new
64
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to']))
65
+ end
66
+
67
+ should "return a error when run with scaffold_for_view and not run any actions" do
68
+ expect_no_actions
69
+ Rails::Generator::Base.logger.expects('error').with('No belongs_to association specified.')
70
+ @generator_script = Rails::Generator::Scripts::Generate.new
71
+ @generator_script.run(generator_script_cmd_line('scaffold_for_view', ['--view', 'belongs_to']))
72
+ end
73
+ end
74
+
75
+ context "A test model with a belongs_to association for a model for which it does not have a name virtual attribute" do
76
+ setup do
77
+ setup_test_model
78
+ setup_parent_test_model
79
+ setup_second_parent_test_model(false)
80
+ end
81
+
82
+ should "return a warning and stop when the problem model is specified" do
83
+ expect_no_actions
84
+ Rails::Generator::Base.logger.expects('warning').with('Model SomeOtherModel does not have a method second_parent_name.')
85
+ @generator_script = Rails::Generator::Scripts::Generate.new
86
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:second_parent'], 'some_other_model'))
87
+ end
88
+
89
+ should "return a warning and not include the problem model when run with view_for but continue to run for other models" do
90
+ stub_actions
91
+ Rails::Generator::Base.logger.expects('warning').with('Model SomeOtherModel does not have a method second_parent_name.')
92
+ Rails::Generator::Commands::Create.any_instance.expects(:directory).with('app/controllers/')
93
+ @generator_script = Rails::Generator::Scripts::Generate.new
94
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to'], 'some_other_model'))
95
+ end
96
+ end
97
+
98
+ context "A test model with a belongs_to association for a model which does not have a name method or column" do
99
+ setup do
100
+ setup_test_model
101
+ setup_parent_test_model
102
+ setup_second_parent_test_model(true, true, false, false)
103
+ end
104
+
105
+ should "return a warning and stop when the problem model is specified" do
106
+ expect_no_actions
107
+ Rails::Generator::Base.logger.expects('warning').with('Model SecondParent does not have a name attribute.')
108
+ @generator_script = Rails::Generator::Scripts::Generate.new
109
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:second_parent'], 'some_other_model'))
110
+ end
111
+
112
+ should "return a warning and not include the problem model when run with view_for but continue to run for other models" do
113
+ stub_actions
114
+ Rails::Generator::Base.logger.expects('warning').with('Model SecondParent does not have a name attribute.')
115
+ Rails::Generator::Commands::Create.any_instance.expects(:directory).with('app/controllers/')
116
+ @generator_script = Rails::Generator::Scripts::Generate.new
117
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to'], 'some_other_model'))
118
+ end
119
+ end
120
+
121
+ context "A test model with a belongs_to association for a model which has a name method but not a name column" do
122
+ setup do
123
+ setup_test_model
124
+ setup_parent_test_model
125
+ setup_second_parent_test_model(true, true, true, false)
126
+ end
127
+
128
+ should "continue to generate as usual" do
129
+ stub_actions
130
+ Rails::Generator::Commands::Create.any_instance.expects(:directory).with('app/controllers/')
131
+ @generator_script = Rails::Generator::Scripts::Generate.new
132
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:second_parent'], 'some_other_model'))
133
+ end
134
+ end
135
+
136
+ context "A test model with a belongs_to association for a model for which it does not have a foreign key" do
137
+ setup do
138
+ setup_test_model
139
+ setup_parent_test_model
140
+ setup_second_parent_test_model(true, false)
141
+ end
142
+
143
+ should "return a warning and stop when the problem model is specified" do
144
+ expect_no_actions
145
+ Rails::Generator::Base.logger.expects('warning').with('Model SomeOtherModel does not contain a foreign key for SecondParent.')
146
+ @generator_script = Rails::Generator::Scripts::Generate.new
147
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:second_parent'], 'some_other_model'))
148
+ end
149
+
150
+ should "return a warning and not include the problem model when run with view_for but continue to run for other models" do
151
+ stub_actions
152
+ Rails::Generator::Base.logger.expects('warning').with('Model SomeOtherModel does not contain a foreign key for SecondParent.')
153
+ Rails::Generator::Commands::Create.any_instance.expects(:directory).with('app/controllers/')
154
+ @generator_script = Rails::Generator::Scripts::Generate.new
155
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to'], 'some_other_model'))
156
+ end
157
+ end
158
+
159
+ context "A view_for generator instantiated for a test model with two belongs_to associations" do
160
+ setup do
161
+ setup_test_model
162
+ setup_parent_test_model
163
+ setup_second_parent_test_model
164
+ @gen = new_generator_for_test_model('view_for', ['--view', 'belongs_to'], 'some_other_model')
165
+ end
166
+
167
+ should "return the proper source root" do
168
+ assert_equal File.expand_path(File.dirname(__FILE__) + '/../../..//lib/view_mapper/views/belongs_to/templates'), ViewMapper::BelongsToView.source_root
169
+ end
170
+
171
+ view_for_templates = %w{ new edit index show }
172
+ view_for_templates.each do | template |
173
+ should "render the #{template} template as expected" do
174
+ @attributes = @gen.attributes
175
+ @singular_name = @gen.singular_name
176
+ @plural_name = @gen.plural_name
177
+ @parent_models = @gen.parent_models
178
+ template_file = File.open(@gen.source_path("view_#{template}.html.erb"))
179
+ result = ERB.new(template_file.read, nil, '-').result(binding)
180
+ expected_file = File.open(File.join(File.dirname(__FILE__), "expected_templates/#{template}.html.erb"))
181
+ assert_equal expected_file.read, result
182
+ end
183
+ end
184
+
185
+ should "render the form template as expected" do
186
+ @attributes = @gen.attributes
187
+ @singular_name = @gen.singular_name
188
+ @plural_name = @gen.plural_name
189
+ @parent_models = @gen.parent_models
190
+ template_file = File.open(@gen.source_path("view_form.html.erb"))
191
+ result = ERB.new(template_file.read, nil, '-').result(binding)
192
+ expected_file = File.open(File.join(File.dirname(__FILE__), "expected_templates/_form.html.erb"))
193
+ assert_equal expected_file.read, result
194
+ end
195
+ end
196
+
197
+ context "A scaffold_for_view generator instantiated for a test model with two belongs_to associations" do
198
+ setup do
199
+ setup_test_model
200
+ setup_parent_test_model
201
+ setup_second_parent_test_model
202
+ @gen = new_generator_for_test_model('scaffold_for_view', ['--view', 'belongs_to:parent,second_parent'], 'some_other_model')
203
+ end
204
+
205
+ should "render the model template as expected" do
206
+ @parent_models = @gen.parent_models
207
+ @class_name = @gen.class_name
208
+ @attributes = @gen.attributes
209
+ template_file = File.open(@gen.source_path("model.rb"))
210
+ result = ERB.new(template_file.read, nil, '-').result(binding)
211
+ expected_file = File.open(File.join(File.dirname(__FILE__), "expected_templates/some_other_model.rb"))
212
+ assert_equal expected_file.read, result
213
+ end
214
+
215
+ should "render the migration template as expected" do
216
+ @class_name = @gen.class_name
217
+ @attributes = @gen.attributes
218
+ @migration_name = 'CreateSomeOtherModels'
219
+ @table_name = @gen.table_name
220
+ @parent_models = @gen.parent_models
221
+ @options = {}
222
+ template_file = File.open(@gen.source_path("migration.rb"))
223
+ result = ERB.new(template_file.read, nil, '-').result(binding)
224
+ expected_file = File.open(File.join(File.dirname(__FILE__), "expected_templates/create_some_other_models.rb"))
225
+ assert_equal expected_file.read, result
226
+ end
227
+ end
228
+
229
+ context "A Rails generator script" do
230
+ setup do
231
+ setup_test_model
232
+ setup_parent_test_model
233
+ @generator_script = Rails::Generator::Scripts::Generate.new
234
+ end
235
+
236
+ should "return a warning when run with view_for on an invalid parent model and not run any actions" do
237
+ expect_no_actions
238
+ Rails::Generator::Base.logger.expects('error').with('Class \'blah\' does not exist or contains a syntax error and could not be loaded.')
239
+ @generator_script = Rails::Generator::Scripts::Generate.new
240
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:blah'], 'some_other_model'))
241
+ end
242
+
243
+ should "create the correct manifest when the view_for generator is run with a valid parent model" do
244
+
245
+ expect_no_warnings
246
+
247
+ directories = [
248
+ 'app/controllers/',
249
+ 'app/helpers/',
250
+ 'app/views/some_other_models',
251
+ 'app/views/layouts/',
252
+ 'test/functional/',
253
+ 'test/unit/',
254
+ 'test/unit/helpers/',
255
+ 'public/stylesheets/'
256
+ ].each { |path| Rails::Generator::Commands::Create.any_instance.expects(:directory).with(path) }
257
+
258
+ templates = {
259
+ 'view_index.html.erb' => 'app/views/some_other_models/index.html.erb',
260
+ 'view_new.html.erb' => 'app/views/some_other_models/new.html.erb',
261
+ 'view_edit.html.erb' => 'app/views/some_other_models/edit.html.erb',
262
+ 'view_show.html.erb' => 'app/views/some_other_models/show.html.erb',
263
+ 'view_form.html.erb' => 'app/views/some_other_models/_form.html.erb',
264
+ 'layout.html.erb' => 'app/views/layouts/some_other_models.html.erb',
265
+ 'style.css' => 'public/stylesheets/scaffold.css',
266
+ 'controller.rb' => 'app/controllers/some_other_models_controller.rb',
267
+ 'functional_test.rb' => 'test/functional/some_other_models_controller_test.rb',
268
+ 'helper.rb' => 'app/helpers/some_other_models_helper.rb',
269
+ 'helper_test.rb' => 'test/unit/helpers/some_other_models_helper_test.rb'
270
+ }.each { |template, target| Rails::Generator::Commands::Create.any_instance.expects(:template).with(template, target) }
271
+
272
+ Rails::Generator::Commands::Create.any_instance.expects(:route_resources).with('some_other_models')
273
+ Rails::Generator::Commands::Create.any_instance.expects(:file).never
274
+ Rails::Generator::Commands::Create.any_instance.expects(:dependency).never
275
+
276
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:parent'], 'some_other_model'))
277
+ end
278
+
279
+ should "create the correct manifest when the scaffold_for_view generator is run with a valid parent model" do
280
+
281
+ expect_no_warnings
282
+
283
+ directories = [
284
+ 'app/models/',
285
+ 'app/controllers/',
286
+ 'app/helpers/',
287
+ 'app/views/some_other_models',
288
+ 'app/views/layouts/',
289
+ 'test/functional/',
290
+ 'test/unit/',
291
+ 'test/unit/helpers/',
292
+ 'test/fixtures/',
293
+ 'public/stylesheets/'
294
+ ].each { |path| Rails::Generator::Commands::Create.any_instance.expects(:directory).with(path) }
295
+
296
+ templates = {
297
+ 'view_index.html.erb' => 'app/views/some_other_models/index.html.erb',
298
+ 'view_new.html.erb' => 'app/views/some_other_models/new.html.erb',
299
+ 'view_edit.html.erb' => 'app/views/some_other_models/edit.html.erb',
300
+ 'view_show.html.erb' => 'app/views/some_other_models/show.html.erb',
301
+ 'view_form.html.erb' => 'app/views/some_other_models/_form.html.erb',
302
+ 'layout.html.erb' => 'app/views/layouts/some_other_models.html.erb',
303
+ 'style.css' => 'public/stylesheets/scaffold.css',
304
+ 'controller.rb' => 'app/controllers/some_other_models_controller.rb',
305
+ 'functional_test.rb' => 'test/functional/some_other_models_controller_test.rb',
306
+ 'helper.rb' => 'app/helpers/some_other_models_helper.rb',
307
+ 'helper_test.rb' => 'test/unit/helpers/some_other_models_helper_test.rb',
308
+ 'model.rb' => 'app/models/some_other_model.rb',
309
+ 'unit_test.rb' => 'test/unit/some_other_model_test.rb',
310
+ 'fixtures.yml' => 'test/fixtures/some_other_models.yml'
311
+ }.each { |template, target| Rails::Generator::Commands::Create.any_instance.expects(:template).with(template, target) }
312
+
313
+ Rails::Generator::Commands::Create.any_instance.expects(:route_resources).with('some_other_models')
314
+ Rails::Generator::Commands::Create.any_instance.expects(:file).never
315
+ Rails::Generator::Commands::Create.any_instance.expects(:dependency).never
316
+
317
+ Rails::Generator::Commands::Create.any_instance.expects(:migration_template).with(
318
+ 'migration.rb',
319
+ 'db/migrate',
320
+ :assigns => { :migration_name => "CreateSomeOtherModels" },
321
+ :migration_file_name => "create_some_other_models"
322
+ )
323
+
324
+ @generator_script.run(generator_script_cmd_line('scaffold_for_view', ['--view', 'belongs_to:parent'], 'some_other_model'))
325
+ end
326
+ end
327
+
328
+ context "A Rails generator script with a parent model without a has_many association" do
329
+ setup do
330
+ setup_test_model
331
+ setup_parent_test_model(true, true, false)
332
+ @generator_script = Rails::Generator::Scripts::Generate.new
333
+ end
334
+
335
+ should "return a warning when run with view_for and not run any actions" do
336
+ expect_no_actions
337
+ Rails::Generator::Base.logger.expects('warning').with('Model Parent does not contain a has_many association for SomeOtherModel.')
338
+ @generator_script.run(generator_script_cmd_line('view_for', ['--view', 'belongs_to:parent'], 'some_other_model'))
339
+ end
340
+
341
+ should "return a warning when run with scaffold_for_view and not run any actions" do
342
+ expect_no_actions
343
+ Rails::Generator::Base.logger.expects('warning').with('Model Parent does not contain a has_many association for SomeOtherModel.')
344
+ @generator_script.run(generator_script_cmd_line('scaffold_for_view', ['--view', 'belongs_to:parent'], 'some_other_model'))
345
+ end
346
+ end
347
+
348
+ end
@@ -0,0 +1,13 @@
1
+ <%= f.error_messages %>
2
+ <p>
3
+ <%= f.label :name %><br />
4
+ <%= f.text_field :name %>
5
+ </p>
6
+ <p>
7
+ Parent:<br />
8
+ <%= f.collection_select(:parent_id, Parent.all, :id, :name, { :prompt => true }) %>
9
+ </p>
10
+ <p>
11
+ Second Parent:<br />
12
+ <%= f.collection_select(:second_parent_id, SecondParent.all, :id, :name, { :prompt => true }) %>
13
+ </p>
@@ -0,0 +1,18 @@
1
+ class CreateSomeOtherModels < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :some_other_models do |t|
4
+ t.string :first_name
5
+ t.string :last_name
6
+ t.string :address
7
+ t.boolean :some_flag
8
+ t.integer :parent_id
9
+ t.integer :second_parent_id
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :some_other_models
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ <h1>Editing some_other_model</h1>
2
+
3
+ <% form_for(@some_other_model) do |f| %>
4
+ <%= render :partial => 'form', :locals => { :f => f } %>
5
+ <p>
6
+ <%= f.submit 'Update' %>
7
+ </p>
8
+ <% end %>
9
+
10
+ <%= link_to 'Show', @some_other_model %> |
11
+ <%= link_to 'Back', some_other_models_path %>
@@ -0,0 +1,24 @@
1
+ <h1>Listing some_other_models</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>Parent</th>
7
+ <th>Second Parent</th>
8
+ </tr>
9
+
10
+ <% @some_other_models.each do |some_other_model| %>
11
+ <tr>
12
+ <td><%=h some_other_model.name %></td>
13
+ <td><%=h some_other_model.parent_name %></td>
14
+ <td><%=h some_other_model.second_parent_name %></td>
15
+ <td><%= link_to 'Show', some_other_model %></td>
16
+ <td><%= link_to 'Edit', edit_some_other_model_path(some_other_model) %></td>
17
+ <td><%= link_to 'Destroy', some_other_model, :confirm => 'Are you sure?', :method => :delete %></td>
18
+ </tr>
19
+ <% end %>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%= link_to 'New some_other_model', new_some_other_model_path %>
@@ -0,0 +1,10 @@
1
+ <h1>New some_other_model</h1>
2
+
3
+ <% form_for(@some_other_model) do |f| %>
4
+ <%= render :partial => 'form', :locals => { :f => f } %>
5
+ <p>
6
+ <%= f.submit 'Create' %>
7
+ </p>
8
+ <% end %>
9
+
10
+ <%= link_to 'Back', some_other_models_path %>
@@ -0,0 +1,17 @@
1
+ <p>
2
+ <b>Name:</b>
3
+ <%=h @some_other_model.name %>
4
+ </p>
5
+
6
+ <p>
7
+ <b>Parent:</b>
8
+ <%=h @some_other_model.parent_name %>
9
+ </p>
10
+
11
+ <p>
12
+ <b>Second Parent:</b>
13
+ <%=h @some_other_model.second_parent_name %>
14
+ </p>
15
+
16
+ <%= link_to 'Edit', edit_some_other_model_path(@some_other_model) %> |
17
+ <%= link_to 'Back', some_other_models_path %>
@@ -0,0 +1,10 @@
1
+ class SomeOtherModel < ActiveRecord::Base
2
+ belongs_to :parent
3
+ belongs_to :second_parent
4
+ def parent_name
5
+ parent.name if parent
6
+ end
7
+ def second_parent_name
8
+ second_parent.name if second_parent
9
+ end
10
+ end
data/view_mapper.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{view_mapper}
8
- s.version = "0.3.1"
8
+ s.version = "0.3.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Pat Shaughnessy"]
12
- s.date = %q{2009-11-25}
12
+ s.date = %q{2010-01-22}
13
13
  s.description = %q{View_mapper will generate scaffolding for new or existing models, customized for the plugins you use in your app.}
14
14
  s.email = %q{pat@patshaughnessy.net}
15
15
  s.extra_rdoc_files = [
@@ -38,6 +38,14 @@ Gem::Specification.new do |s|
38
38
  "lib/view_mapper/views/auto_complete/templates/layout.html.erb",
39
39
  "lib/view_mapper/views/auto_complete/templates/view_edit.html.erb",
40
40
  "lib/view_mapper/views/auto_complete/templates/view_new.html.erb",
41
+ "lib/view_mapper/views/belongs_to/belongs_to_view.rb",
42
+ "lib/view_mapper/views/belongs_to/templates/migration.rb",
43
+ "lib/view_mapper/views/belongs_to/templates/model.rb",
44
+ "lib/view_mapper/views/belongs_to/templates/view_edit.html.erb",
45
+ "lib/view_mapper/views/belongs_to/templates/view_form.html.erb",
46
+ "lib/view_mapper/views/belongs_to/templates/view_index.html.erb",
47
+ "lib/view_mapper/views/belongs_to/templates/view_new.html.erb",
48
+ "lib/view_mapper/views/belongs_to/templates/view_show.html.erb",
41
49
  "lib/view_mapper/views/has_many/has_many_view.rb",
42
50
  "lib/view_mapper/views/has_many/templates/helper.rb",
43
51
  "lib/view_mapper/views/has_many/templates/layout.html.erb",
@@ -75,6 +83,14 @@ Gem::Specification.new do |s|
75
83
  "test/views/auto_complete/expected_templates/standard_routes.rb",
76
84
  "test/views/auto_complete/expected_templates/testies.html.erb",
77
85
  "test/views/auto_complete/expected_templates/testies_controller.rb",
86
+ "test/views/belongs_to/belongs_to_test.rb",
87
+ "test/views/belongs_to/expected_templates/_form.html.erb",
88
+ "test/views/belongs_to/expected_templates/create_some_other_models.rb",
89
+ "test/views/belongs_to/expected_templates/edit.html.erb",
90
+ "test/views/belongs_to/expected_templates/index.html.erb",
91
+ "test/views/belongs_to/expected_templates/new.html.erb",
92
+ "test/views/belongs_to/expected_templates/show.html.erb",
93
+ "test/views/belongs_to/expected_templates/some_other_model.rb",
78
94
  "test/views/fake/fake_view.rb",
79
95
  "test/views/fake/templates/fake_template1.html.erb",
80
96
  "test/views/has_many/expected_templates/_form.html.erb",
@@ -113,6 +129,9 @@ Gem::Specification.new do |s|
113
129
  "test/views/auto_complete/expected_templates/expected_routes.rb",
114
130
  "test/views/auto_complete/expected_templates/standard_routes.rb",
115
131
  "test/views/auto_complete/expected_templates/testies_controller.rb",
132
+ "test/views/belongs_to/belongs_to_test.rb",
133
+ "test/views/belongs_to/expected_templates/create_some_other_models.rb",
134
+ "test/views/belongs_to/expected_templates/some_other_model.rb",
116
135
  "test/views/fake/fake_view.rb",
117
136
  "test/views/has_many/expected_templates/create_parents.rb",
118
137
  "test/views/has_many/expected_templates/parent.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Shaughnessy
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-25 00:00:00 -05:00
12
+ date: 2010-01-22 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -63,6 +63,14 @@ files:
63
63
  - lib/view_mapper/views/auto_complete/templates/layout.html.erb
64
64
  - lib/view_mapper/views/auto_complete/templates/view_edit.html.erb
65
65
  - lib/view_mapper/views/auto_complete/templates/view_new.html.erb
66
+ - lib/view_mapper/views/belongs_to/belongs_to_view.rb
67
+ - lib/view_mapper/views/belongs_to/templates/migration.rb
68
+ - lib/view_mapper/views/belongs_to/templates/model.rb
69
+ - lib/view_mapper/views/belongs_to/templates/view_edit.html.erb
70
+ - lib/view_mapper/views/belongs_to/templates/view_form.html.erb
71
+ - lib/view_mapper/views/belongs_to/templates/view_index.html.erb
72
+ - lib/view_mapper/views/belongs_to/templates/view_new.html.erb
73
+ - lib/view_mapper/views/belongs_to/templates/view_show.html.erb
66
74
  - lib/view_mapper/views/has_many/has_many_view.rb
67
75
  - lib/view_mapper/views/has_many/templates/helper.rb
68
76
  - lib/view_mapper/views/has_many/templates/layout.html.erb
@@ -100,6 +108,14 @@ files:
100
108
  - test/views/auto_complete/expected_templates/standard_routes.rb
101
109
  - test/views/auto_complete/expected_templates/testies.html.erb
102
110
  - test/views/auto_complete/expected_templates/testies_controller.rb
111
+ - test/views/belongs_to/belongs_to_test.rb
112
+ - test/views/belongs_to/expected_templates/_form.html.erb
113
+ - test/views/belongs_to/expected_templates/create_some_other_models.rb
114
+ - test/views/belongs_to/expected_templates/edit.html.erb
115
+ - test/views/belongs_to/expected_templates/index.html.erb
116
+ - test/views/belongs_to/expected_templates/new.html.erb
117
+ - test/views/belongs_to/expected_templates/show.html.erb
118
+ - test/views/belongs_to/expected_templates/some_other_model.rb
103
119
  - test/views/fake/fake_view.rb
104
120
  - test/views/fake/templates/fake_template1.html.erb
105
121
  - test/views/has_many/expected_templates/_form.html.erb
@@ -160,6 +176,9 @@ test_files:
160
176
  - test/views/auto_complete/expected_templates/expected_routes.rb
161
177
  - test/views/auto_complete/expected_templates/standard_routes.rb
162
178
  - test/views/auto_complete/expected_templates/testies_controller.rb
179
+ - test/views/belongs_to/belongs_to_test.rb
180
+ - test/views/belongs_to/expected_templates/create_some_other_models.rb
181
+ - test/views/belongs_to/expected_templates/some_other_model.rb
163
182
  - test/views/fake/fake_view.rb
164
183
  - test/views/has_many/expected_templates/create_parents.rb
165
184
  - test/views/has_many/expected_templates/parent.rb