contentator 0.2.0 → 0.2.1

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 (101) hide show
  1. data/README.rdoc +2 -2
  2. data/Rakefile +26 -0
  3. data/VERSION +1 -0
  4. data/app/controllers/application_controller.rb +35 -0
  5. data/app/controllers/cms/admin/admin_controller.rb +3 -0
  6. data/app/controllers/cms/admin/file_attachments_controller.rb +53 -0
  7. data/app/controllers/cms/admin/page_content_blocks_controller.rb +77 -0
  8. data/app/controllers/cms/admin/pages_controller.rb +68 -0
  9. data/app/controllers/cms/content_controller.rb +25 -0
  10. data/app/helpers/application_helper.rb +29 -0
  11. data/app/helpers/cms/admin/pages_helper.rb +34 -0
  12. data/app/models/file_attachment.rb +4 -0
  13. data/app/models/page.rb +71 -0
  14. data/app/models/page_content_block.rb +10 -0
  15. data/app/views/cms/admin/_admin_toolbar.html.haml +10 -0
  16. data/app/views/cms/admin/file_attachments/_form.html.haml +17 -0
  17. data/app/views/cms/admin/page_content_blocks/_form.html.haml +23 -0
  18. data/app/views/cms/admin/pages/_form.html.haml +22 -0
  19. data/app/views/cms/admin/pages/edit.html.haml +10 -0
  20. data/app/views/cms/admin/pages/index.html.haml +13 -0
  21. data/app/views/cms/admin/pages/new.html.haml +7 -0
  22. data/app/views/cms/content/_file_attachment.html.haml +9 -0
  23. data/app/views/cms/content/_file_attachments_container.html.haml +16 -0
  24. data/app/views/cms/content/_page_content_block.html.haml +14 -0
  25. data/app/views/cms/content/_page_content_blocks_container.html.haml +15 -0
  26. data/app/views/cms/content/content.html.haml +4 -0
  27. data/app/views/cms/content/gallery.html.haml +4 -0
  28. data/app/views/cms/content/home.html.haml +4 -0
  29. data/app/views/layouts/application.html.haml +22 -0
  30. data/app/views/layouts/cms/admin/application.html.haml +44 -0
  31. data/config/boot.rb +110 -0
  32. data/config/environment.rb +54 -0
  33. data/config/environments/development.rb +17 -0
  34. data/config/environments/production.rb +28 -0
  35. data/config/environments/test.rb +28 -0
  36. data/config/geminstaller.local.yml +21 -0
  37. data/config/geminstaller.yml +22 -0
  38. data/config/initializers/backtrace_silencers.rb +7 -0
  39. data/config/initializers/inflections.rb +10 -0
  40. data/config/initializers/mime_types.rb +5 -0
  41. data/config/initializers/new_rails_defaults.rb +19 -0
  42. data/config/initializers/session_store.rb +15 -0
  43. data/config/locales/de.yml +49 -0
  44. data/config/locales/en.yml +49 -0
  45. data/config/routes.rb +13 -0
  46. data/contentator.gemspec +160 -0
  47. data/db/migrate/20091002165818_create_pages.rb +22 -0
  48. data/db/migrate/20091002211930_create_home_page.rb +10 -0
  49. data/db/migrate/20091007222703_create_page_content_blocks.rb +22 -0
  50. data/db/migrate/20091029204950_create_file_attachments.rb +17 -0
  51. data/lib/contentator.rb +2 -0
  52. data/lib/generators/content/content_generator.rb +118 -0
  53. data/lib/generators/content/templates/container.rb +16 -0
  54. data/lib/generators/content/templates/controller.rb +63 -0
  55. data/lib/generators/content/templates/factories.rb +6 -0
  56. data/lib/generators/content/templates/form.rb +12 -0
  57. data/lib/generators/content/templates/functional_test.rb +140 -0
  58. data/lib/generators/content/templates/item.rb +11 -0
  59. data/lib/generators/content/templates/migration.rb +17 -0
  60. data/lib/generators/content/templates/model.rb +5 -0
  61. data/lib/generators/content/templates/unit_test.rb +8 -0
  62. data/lib/generators/content/templates/view.rb +0 -0
  63. data/lib/template.rb +10 -0
  64. data/public/404.html +30 -0
  65. data/public/422.html +30 -0
  66. data/public/500.html +30 -0
  67. data/public/favicon.ico +0 -0
  68. data/public/images/admin_standard/content-header-bg.png +0 -0
  69. data/public/images/admin_standard/context-arrow.png +0 -0
  70. data/public/images/admin_standard/context-bg.png +0 -0
  71. data/public/images/admin_standard/crumb-bg-current.gif +0 -0
  72. data/public/images/admin_standard/crumb-bg.gif +0 -0
  73. data/public/images/admin_standard/crumb-divide-current.gif +0 -0
  74. data/public/images/admin_standard/crumb-divide.gif +0 -0
  75. data/public/images/admin_standard/drawer-end.png +0 -0
  76. data/public/images/admin_standard/drawer-middle.png +0 -0
  77. data/public/images/admin_standard/drawer-start.png +0 -0
  78. data/public/images/admin_standard/form-error.png +0 -0
  79. data/public/images/admin_standard/input-background.gif +0 -0
  80. data/public/images/admin_standard/shadow-bottom.png +0 -0
  81. data/public/images/admin_standard/shadow-right.png +0 -0
  82. data/public/images/admin_standard/subnavigation-bullet-1.png +0 -0
  83. data/public/images/admin_standard/subnavigation-bullet-2.png +0 -0
  84. data/public/images/admin_standard/tab-active-cap.png +0 -0
  85. data/public/images/admin_standard/tab-active.png +0 -0
  86. data/public/images/admin_standard/tab-inactive-cap.png +0 -0
  87. data/public/images/admin_standard/tab-inactive.png +0 -0
  88. data/public/images/blank.gif +0 -0
  89. data/public/images/icons/add.png +0 -0
  90. data/public/images/icons/cancel.png +0 -0
  91. data/public/images/icons/delete.png +0 -0
  92. data/public/images/icons/edit.png +0 -0
  93. data/public/images/icons/folder.png +0 -0
  94. data/public/images/icons/move.png +0 -0
  95. data/public/images/rails.png +0 -0
  96. data/public/robots.txt +5 -0
  97. data/public/stylesheets/admin_standard.css +877 -0
  98. data/public/stylesheets/application.css +33 -0
  99. data/rails_generators/contentator_files/contentator_files_generator.rb +127 -0
  100. data/rails_generators/contentator_files/templates/application.rb +5 -0
  101. metadata +111 -2
@@ -0,0 +1,10 @@
1
+ class CreateHomePage < ActiveRecord::Migration
2
+ def self.up
3
+ execute "INSERT INTO `pages` (id,title,template_name,slug,position,visible) VALUES (1,'Home', 'home','home',1,1)"
4
+ execute "INSERT INTO `page_translations` (page_id,locale,title,template_name) VALUES (1, 'en', 'Home', 'home')"
5
+ end
6
+
7
+ def self.down
8
+ Page.find_by_id(1).destroy
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ class CreatePageContentBlocks < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :page_content_blocks do |t|
4
+ t.references :page
5
+ t.string :title
6
+ t.text :text
7
+ t.integer :position
8
+ t.boolean :visible
9
+ t.string :photo_file_name
10
+ t.string :photo_content_type
11
+ t.integer :photo_file_size
12
+ t.string :size
13
+ t.timestamps
14
+ end
15
+ PageContentBlock.create_translation_table! :title => :string, :text => :text
16
+ end
17
+
18
+ def self.down
19
+ drop_table :page_content_blocks
20
+ PageContentBlock.drop_translation_table!
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ class CreateFileAttachments < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :file_attachments do |t|
4
+ t.references :owner, :polymorphic => true
5
+ t.integer :position
6
+ t.boolean :visible
7
+ t.string :file_file_name
8
+ t.string :file_content_type
9
+ t.integer :file_file_size
10
+ t.timestamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :file_attachments
16
+ end
17
+ end
@@ -0,0 +1,2 @@
1
+ module Contentator
2
+ end
@@ -0,0 +1,118 @@
1
+ module Rails
2
+ module Generator
3
+ module Commands
4
+ class Create
5
+ def create_factory
6
+ template = File.read(source_path('factories.rb'))
7
+ source_to_update = ERB.new(template, nil, '-').result(binding)
8
+ File.open('test/factories.rb', 'a') { |file| file.write("\n\n#{source_to_update}") }
9
+ end
10
+ def route_namespaced_resources(resource)
11
+ sentinel = "cms.namespace :admin, :path_prefix => '' do |admin|"
12
+ logger.route "admin.resources #{resource}"
13
+ unless options[:pretend]
14
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
15
+ "#{match}\n\t\t\tadmin.resources :#{resource}, :collection => [:sort], :only => [:new, :create, :update, :edit, :destroy]"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ class Destroy
21
+ def create_factory
22
+ # pass can't undo right now
23
+ end
24
+ def route_namespaced_resources(resource)
25
+ # pass can't undo right now
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class ContentGenerator < Rails::Generator::NamedBase
33
+ attr_reader :controller_name,
34
+ :controller_class_path,
35
+ :controller_file_path,
36
+ :controller_class_nesting,
37
+ :controller_class_nesting_depth,
38
+ :controller_class_name,
39
+ :controller_singular_name,
40
+ :controller_plural_name
41
+ alias_method :controller_file_name, :controller_singular_name
42
+ alias_method :controller_table_name, :controller_plural_name
43
+
44
+ def initialize(runtime_args, runtime_options = {})
45
+ super
46
+
47
+ @controller_name = @name.pluralize
48
+
49
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
50
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
51
+
52
+ if @controller_class_nesting.empty?
53
+ @controller_class_name = @controller_class_name_without_nesting
54
+ else
55
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
56
+ end
57
+ end
58
+
59
+ def manifest
60
+ record do |m|
61
+ #add position to attributes if not there already
62
+ attributes << Rails::Generator::GeneratedAttribute.new('position', 'integer') unless attributes.map{|att| att.name == 'position'}
63
+
64
+ # Check for class naming collisions.
65
+ m.class_collisions(class_name, "#{class_name}Test", "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper")
66
+
67
+ #namespace route under :cms :admin
68
+ m.route_namespaced_resources(controller_file_name)
69
+
70
+ # Controller, helper, views, and test directories.
71
+ m.directory(File.join('app/models', class_path))
72
+ m.directory(File.join('app/controllers/cms/admin', controller_class_path))
73
+ m.directory(File.join('test/functional/cms/admin', controller_class_path))
74
+ m.directory(File.join('test/unit', class_path))
75
+ m.directory(File.join('app/views/cms/admin', controller_class_path, controller_file_name))
76
+
77
+ m.template('controller.rb', File.join('app/controllers/cms/admin', controller_class_path, "#{controller_file_name}_controller.rb"))
78
+ m.template('functional_test.rb', File.join('test/functional/cms/admin', controller_class_path, "#{controller_file_name}_controller_test.rb"))
79
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
80
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
81
+
82
+ #make view code for model form and containers
83
+ m.template 'form.rb', File.join('app/views/cms/admin', class_path, table_name, '_form.html.haml')
84
+ m.template 'container.rb', File.join('app/views/cms/content', class_path, "_#{table_name}_container.html.haml")
85
+ m.template 'item.rb', File.join('app/views/cms/content', class_path, "_#{file_name}.html.haml")
86
+
87
+ m.create_factory
88
+
89
+ #make migration
90
+ unless options[:skip_migration]
91
+ m.migration_template 'migration.rb', 'db/migrate', :assigns => {
92
+ :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
93
+ }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
94
+ end
95
+ end
96
+ end
97
+
98
+ protected
99
+ def banner
100
+ "Usage: #{$0} content ModelName [field:type, field:type]"
101
+ end
102
+
103
+ def add_options!(opt)
104
+ opt.separator ''
105
+ opt.separator 'Options:'
106
+ opt.on("--skip-timestamps",
107
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
108
+ opt.on("--skip-migration",
109
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
110
+ end
111
+
112
+ def gsub_file(relative_destination, regexp, *args, &block)
113
+ path = destination_path(relative_destination)
114
+ content = File.read(path).gsub(regexp, *args, &block)
115
+ File.open(path, 'wb') { |file| file.write(content) }
116
+ end
117
+
118
+ end
@@ -0,0 +1,16 @@
1
+ #new_<%= file_name %>_container
2
+
3
+ - <%= class_name %>.all.each do |<%= file_name %>|
4
+ = render :partial => 'cms/content/<%= file_name %>', :locals => {:<%= file_name %> => <%= file_name %>}
5
+
6
+ - if current_user
7
+ :javascript
8
+ Sortable.create('<%= table_name %>_container', {tag: 'div', handle: 'sort-handle',
9
+ only: 'box',
10
+ onUpdate: function() {
11
+ new Ajax.Request('#{sort_cms_admin_<%= table_name %>_path}?page_id=#{@page.id}', {
12
+ method: 'get',
13
+ parameters: Sortable.serialize('<%= table_name %>_container', {tag: 'div', name: '<%= file_name %>'})
14
+ });
15
+ }
16
+ });
@@ -0,0 +1,63 @@
1
+ class Cms::Admin::<%= controller_class_name %>Controller < ApplicationController
2
+
3
+ def new
4
+ @<%= file_name %> = <%= class_name %>.new
5
+ @page = Page.find(params[:page_id])
6
+ render :partial => 'cms/admin/<%= table_name %>/form'
7
+ end
8
+
9
+ def create
10
+ @page = Page.find(params[:<%= file_name %>].delete('page_id'))
11
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
12
+
13
+ if @<%= file_name %>.save
14
+ render :update do |page|
15
+ page.replace_html 'new_<%= file_name %>_container', ''
16
+ page.replace_html '<%= table_name %>_container', :partial => 'cms/content/<%= table_name %>_container'
17
+ end
18
+ else
19
+ render :update do |page|
20
+ page.replace_html 'new_<%= file_name %>_container', :partial => 'cms/admin/<%= table_name %>/form'
21
+ end
22
+ end
23
+ end
24
+
25
+ def edit
26
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
27
+ @page = Page.find(params[:page_id])
28
+ render :partial => 'cms/admin/<%= table_name %>/form'
29
+ end
30
+
31
+ def update
32
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
33
+ @page = Page.find(params[:<%= file_name %>].delete('page_id'))
34
+
35
+ if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
36
+ render :update do |page|
37
+ page.replace_html '<%= table_name %>_container', :partial => 'cms/content/<%= table_name %>_container'
38
+ end
39
+ else
40
+ render :update do |page|
41
+ page.replace_html "<%= file_name %>_", :partial => 'cms/admin/<%= table_name %>/form'
42
+ end
43
+ end
44
+ end
45
+
46
+ def destroy
47
+ @page = Page.find(params[:page_id])
48
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
49
+ @<%= file_name %>.destroy
50
+ render :partial => 'cms/content/<%= table_name %>_container'
51
+ end
52
+
53
+ def sort
54
+ @page = Page.find(params[:page_id])
55
+ if params[:<%= table_name %>]
56
+ params[:<%= table_name %>].each do |k,v|
57
+ <%= file_name %> = <%= class_name %>.find(k)
58
+ <%= file_name %>.update_attributes(:position => v)
59
+ end
60
+ end
61
+ redirect_to content_path(@page.path)
62
+ end
63
+ end
@@ -0,0 +1,6 @@
1
+ Factory.define :<%= singular_name %> do |f|
2
+ <% for attribute in attributes -%>
3
+ f.<%= attribute.name %> <%= attribute.default.is_a?(String) ? "'#{attribute.default}'" : attribute.default %>
4
+ <% end -%>
5
+ f.updated_at '2009-04-01 12:00:00'
6
+ end
@@ -0,0 +1,12 @@
1
+ .form_container
2
+ = link_to image_tag('icons/cancel.png'), content_path(@page.path), :id => 'cancel_button'
3
+
4
+ - form_remote_for([:cms, :admin, @<%= file_name %>], :html => {:multipart => true }) do |f|
5
+ = f.hidden_field :page_id, :value => @page.id
6
+
7
+ <% for attribute in attributes -%>
8
+ = f.label :<%= attribute.name %>
9
+ = f.text_field :<%= attribute.name %>
10
+
11
+ <% end %>
12
+ = submit_tag "Submit"
@@ -0,0 +1,140 @@
1
+ require 'test_helper'
2
+
3
+ class Cms::Admin::<%= controller_class_name %>ControllerTest < ActionController::TestCase
4
+ context '<%= controller_class_name.underscore %> controller' do
5
+
6
+ setup do
7
+ @page = Factory(:page)
8
+ @<%= file_name %> = Factory(:<%= file_name %>)
9
+ @<%= file_name %>2 = Factory(:<%= file_name %>, :position => 2)
10
+ end
11
+
12
+ should "route" do
13
+ assert_recognizes(
14
+ {:controller => "cms/admin/<%= table_name %>", :action => 'sort'},
15
+ {:path => '/admin/<%= table_name %>/sort', :method => :post}
16
+ )
17
+ assert_recognizes(
18
+ {:controller => "cms/admin/<%= table_name %>", :action => 'create'},
19
+ {:path => '/admin/<%= table_name %>/', :method => :post}
20
+ )
21
+ assert_recognizes(
22
+ {:controller => "cms/admin/<%= table_name %>", :action => 'new'},
23
+ {:path => '/admin/<%= table_name %>/new', :method => :get}
24
+ )
25
+ assert_recognizes(
26
+ {:controller => "cms/admin/<%= table_name %>", :action => 'edit', :id => '1'},
27
+ {:path => '/admin/<%= table_name %>/1/edit', :method => :get}
28
+ )
29
+ assert_recognizes(
30
+ {:controller => "cms/admin/<%= table_name %>", :action => 'update', :id => '1'},
31
+ {:path => '/admin/<%= table_name %>/1', :method => :put}
32
+ )
33
+ assert_equal('/admin/<%= table_name %>/sort', sort_cms_admin_<%= table_name %>_path())
34
+ assert_equal('/admin/<%= table_name %>', cms_admin_<%= table_name %>_path())
35
+ assert_equal('/admin/<%= table_name %>/new', new_cms_admin_<%= file_name %>_path())
36
+ assert_equal('/admin/<%= table_name %>/1/edit', edit_cms_admin_<%= file_name %>_path(1))
37
+ assert_equal('/admin/<%= table_name %>/1', cms_admin_<%= file_name %>_path(1))
38
+ end
39
+
40
+ context "on GET to :new" do
41
+ setup { get :new, :page_id => @page.id }
42
+
43
+ should_assign_to :<%= file_name %>
44
+ should_respond_with :success
45
+ should_render_template :form
46
+ end
47
+
48
+ context "on GET to :edit" do
49
+ setup { get :edit, :page_id => @page.id, :id => @<%= file_name %>.id }
50
+
51
+ should_assign_to :<%= file_name %>
52
+ should_respond_with :success
53
+ should_render_template :form
54
+ end
55
+
56
+ context "stubbed valid <%= file_name %>" do
57
+ setup do
58
+ <%= class_name %>.any_instance.stubs(:valid?).returns(true)
59
+ end
60
+
61
+ context "on POST to :create" do
62
+ setup do
63
+ post :create, :page_id => @page.id, :<%= file_name %> => Factory.attributes_for(:<%= file_name %>).merge(:page_id => @page.id)
64
+ end
65
+
66
+ should_change('the number of <%= table_name %>', :by => 1 ) { <%= class_name %>.count }
67
+ should_assign_to :<%= file_name %>
68
+ should_render_template :<%= table_name %>_container
69
+
70
+ should "save to db" do
71
+ assert !assigns(:<%= file_name %>).new_record?
72
+ end
73
+ end
74
+
75
+ context "on PUT to :update" do
76
+ setup do
77
+ put :update, :id => @<%= file_name %>.id, :<%= file_name %> => {:<%= attributes.first.name %> => <%= attributes.first.default.is_a?(String) ? "'#{attributes.first.default}_hello'" : attributes.first.default+1 %>, :page_id => @page.id}
78
+ end
79
+
80
+ should_assign_to :<%= file_name %>
81
+ should_change('<%= file_name %> updated' ) { @<%= file_name %>.reload.updated_at }
82
+ should_render_template :<%= table_name %>_container
83
+ end
84
+ end
85
+
86
+ context "stubbed invalid <%= file_name %>" do
87
+ setup do
88
+ <%= class_name %>.any_instance.stubs(:valid?).returns(false)
89
+ end
90
+
91
+ context "on POST to :create" do
92
+ setup do
93
+ post :create, :<%= file_name %> => Factory.attributes_for(:<%= file_name %>).merge(:page_id => @page.id)
94
+ end
95
+
96
+ should_not_change('the number of <%= table_name %>') {<%= class_name %>.count}
97
+ should_assign_to :<%= file_name %>
98
+ should_render_template :form
99
+
100
+ should "not save to db" do
101
+ assert assigns(:<%= file_name %>).new_record?
102
+ end
103
+ end
104
+
105
+ context "on PUT to :update" do
106
+ setup do
107
+ put :update, :id => @<%= file_name %>.id, :<%= file_name %> => { :updated_at => Time.now, :page_id => @page.id}
108
+ end
109
+
110
+ should_not_change('<%= file_name %> updated' ) { <%= class_name %>.find(@<%= file_name %>.id).updated_at }
111
+ should_assign_to :<%= file_name %>
112
+ should_render_template :form
113
+ end
114
+ end
115
+
116
+ # must not be a parent of anything
117
+ context "on DELETE to :destroy" do
118
+ setup { get :destroy, :id => @<%= file_name %>.id, :page_id => @page.id}
119
+
120
+ should_change('the number of <%= table_name %>', :by => -1 ) { <%= class_name %>.count }
121
+ should_assign_to :<%= file_name %>
122
+ should_render_template :<%= table_name %>_container
123
+ end
124
+
125
+ context "on POST to :sort" do
126
+ setup do
127
+ post :sort, :page_id => @page.id, :<%= table_name %> => {@<%= file_name %>.id => '2', @<%= file_name %>2.id => '1'}
128
+ end
129
+
130
+ should "sort <%= table_name %>" do
131
+ assert_equal 2, @<%= file_name %>.reload.position
132
+ assert_equal 1, @<%= file_name %>2.reload.position
133
+ end
134
+
135
+ should_assign_to :page
136
+ should_redirect_to('content path') { content_path(@page.path) }
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,11 @@
1
+ - id = <%= file_name %>.id
2
+ %a{:name => id}
3
+ %div{:class => '<%= file_name %>', :id => "<%= file_name %>_#{id}"}
4
+ = delete_link("<%= file_name %>_#{id}", cms_admin_<%= file_name %>_path(id))
5
+ = edit_link("<%= file_name %>#{id}", edit_cms_admin_<%= file_name %>_path(id))
6
+ = sort_field(id,<%= file_name %>.position)
7
+
8
+ .clear
9
+ <% for attribute in attributes -%>
10
+ .<%= attribute.name %>= <%= file_name %>.<%= attribute.name %> unless <%= file_name %>.<%= attribute.name %>.blank?
11
+ <% end -%>
@@ -0,0 +1,17 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ t.integer :position
5
+ <% for attribute in attributes -%>
6
+ t.<%= attribute.type %> :<%= attribute.name %>
7
+ <% end -%>
8
+ <% unless options[:skip_timestamps] %>
9
+ t.timestamps
10
+ <% end -%>
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :<%= table_name %>
16
+ end
17
+ end