view_mapper 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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