schemaless 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +93 -0
  3. data/Rakefile +18 -0
  4. data/lib/generators/schemaless/migrations/USAGE +8 -0
  5. data/lib/generators/schemaless/migrations/migrations_generator.rb +108 -0
  6. data/lib/generators/schemaless/migrations/templates/change_table.rb +34 -0
  7. data/lib/generators/schemaless/migrations/templates/create_table.rb +18 -0
  8. data/lib/generators/schemaless/setup/setup_generator.rb +17 -0
  9. data/lib/generators/schemaless/setup/templates/schemaless.rb +3 -0
  10. data/lib/schemaless/ar/fields.rb +76 -0
  11. data/lib/schemaless/ar/indexes.rb +46 -0
  12. data/lib/schemaless/ar/stubs.rb +15 -0
  13. data/lib/schemaless/field.rb +94 -0
  14. data/lib/schemaless/index.rb +59 -0
  15. data/lib/schemaless/railtie.rb +23 -0
  16. data/lib/schemaless/table.rb +95 -0
  17. data/lib/schemaless/version.rb +4 -0
  18. data/lib/schemaless/worker.rb +47 -0
  19. data/lib/schemaless.rb +21 -0
  20. data/lib/tasks/schemaless_tasks.rake +23 -0
  21. data/spec/dummy/README.rdoc +28 -0
  22. data/spec/dummy/Rakefile +6 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  26. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  27. data/spec/dummy/app/models/bike.rb +18 -0
  28. data/spec/dummy/app/models/place.rb +8 -0
  29. data/spec/dummy/app/models/rider.rb +8 -0
  30. data/spec/dummy/app/models/user.rb +21 -0
  31. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  32. data/spec/dummy/bin/bundle +3 -0
  33. data/spec/dummy/bin/rails +4 -0
  34. data/spec/dummy/bin/rake +4 -0
  35. data/spec/dummy/config/application.rb +28 -0
  36. data/spec/dummy/config/boot.rb +5 -0
  37. data/spec/dummy/config/database.yml +25 -0
  38. data/spec/dummy/config/environment.rb +5 -0
  39. data/spec/dummy/config/environments/development.rb +37 -0
  40. data/spec/dummy/config/environments/production.rb +78 -0
  41. data/spec/dummy/config/environments/test.rb +39 -0
  42. data/spec/dummy/config/initializers/assets.rb +8 -0
  43. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/spec/dummy/config/initializers/inflections.rb +16 -0
  47. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  48. data/spec/dummy/config/initializers/session_store.rb +3 -0
  49. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/spec/dummy/config/locales/en.yml +23 -0
  51. data/spec/dummy/config/routes.rb +56 -0
  52. data/spec/dummy/config/secrets.yml +22 -0
  53. data/spec/dummy/config.ru +4 -0
  54. data/spec/dummy/db/development.sqlite3 +0 -0
  55. data/spec/dummy/db/migrate/20141202223732_create_bikes.rb +16 -0
  56. data/spec/dummy/db/migrate/20141202223750_create_places.rb +9 -0
  57. data/spec/dummy/db/migrate/20141202223751_create_riders.rb +10 -0
  58. data/spec/dummy/db/migrate/20141202223752_create_users.rb +8 -0
  59. data/spec/dummy/db/migrate/20141202223753_create_user_skills.rb +8 -0
  60. data/spec/dummy/db/migrate/20141202223754_create_user_extras.rb +8 -0
  61. data/spec/dummy/db/production.sqlite3 +0 -0
  62. data/spec/dummy/db/test.sqlite3 +0 -0
  63. data/spec/dummy/log/development.log +213 -0
  64. data/spec/dummy/log/test.log +185888 -0
  65. data/spec/dummy/public/404.html +67 -0
  66. data/spec/dummy/public/422.html +67 -0
  67. data/spec/dummy/public/500.html +66 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/generators/schemaless/migrations/migration_generator_spec.rb +14 -0
  70. data/spec/locales/en.yml +15 -0
  71. data/spec/locales/pt.yml +27 -0
  72. data/spec/schemaless/ar/fields_spec.rb +45 -0
  73. data/spec/schemaless/ar/indexes_spec.rb +43 -0
  74. data/spec/schemaless/field_spec.rb +29 -0
  75. data/spec/schemaless/index_spec.rb +9 -0
  76. data/spec/schemaless/table_spec.rb +25 -0
  77. data/spec/schemaless/worker_spec.rb +57 -0
  78. data/spec/schemaless_spec.rb +15 -0
  79. data/spec/spec_helper.rb +57 -0
  80. data/spec/support/001_create_testing_structure.rb +36 -0
  81. metadata +309 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'MigrationGenerator' do
4
+
5
+ it 'should generate a nice migration for the app' do
6
+ expect { Schemaless::Worker.generate! }.to_not raise_error
7
+ end
8
+
9
+ it 'should generate a nice migration for the app' do
10
+ pending
11
+ Schemaless::MigrationGenerator.new(['rock'], data).invoke
12
+ end
13
+
14
+ end
@@ -0,0 +1,15 @@
1
+ en:
2
+ activerecord:
3
+ attributes:
4
+ schemalesss:
5
+ user:
6
+ language:
7
+ pt: Portuguese
8
+ en: English
9
+ sex:
10
+ "true": Female
11
+ "false": Male
12
+ user_skill:
13
+ kind:
14
+ magic: Magic
15
+ agility: Agility
@@ -0,0 +1,27 @@
1
+ pt:
2
+ activerecord:
3
+ schemalesss:
4
+ user:
5
+ role: reader
6
+ status:
7
+ active: Active
8
+ inactive: Inactive
9
+ gui:
10
+ cocoa: cocoa
11
+ gtk: gtk
12
+ qt: qt
13
+ country:
14
+ pt: Pt
15
+ language:
16
+ pt: Português
17
+ en: Inglês
18
+ sex:
19
+ "true": Feminino
20
+ "false": Masculino
21
+ user_skill:
22
+ kind:
23
+ magic: Mágica
24
+ agility: Agilidade
25
+ errors:
26
+ messages: &errors_messages
27
+ record_invalid: Inválido
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'Schemaless' do
5
+ it 'should respond to schemaless' do
6
+ expect(ActiveRecord::Base).to respond_to :field
7
+ end
8
+
9
+ it 'should get all models`s fields' do
10
+ expect(Bike.schemaless_fields.map(&:name)).to include('cylinders')
11
+ end
12
+
13
+ it 'should get a model current attributes' do
14
+ expect(Bike.current_attributes.first).to be_a(::Schemaless::Field)
15
+ end
16
+
17
+ it 'should have a helper for timestamps' do
18
+ expect(Bike.schemaless_fields.map(&:name)).to include('created_at')
19
+ expect(Bike.schemaless_fields.map(&:name)).to include('updated_at')
20
+ end
21
+
22
+ # it 'should get attribute type string' do
23
+ # expect(Bike.schemaless_fields[:attr_db]['name']).to eq(:string)
24
+ # end
25
+
26
+ # it 'should get attribute type integer' do
27
+ # expect(Schemaless.schema['Bike'][:attr_db]['cylinders']).to eq(:integer)
28
+ # end
29
+
30
+ # it 'should not include primary keys' do
31
+ # expect(Schemaless.schema['Bike'][:attr_db]).to_not include('id')
32
+ # end
33
+
34
+ # it 'should get all models`s fields' do
35
+ # expect(Schemaless.schema['Bike'][:model]).to eq(Bike)
36
+ # end
37
+
38
+ # it 'should not include primary keys' do
39
+ # expect(Schemaless.schema['Bike'][:attr_schema]).to include('cc')
40
+ # end
41
+
42
+ # it 'should get schemaless types' do
43
+ # expect(Schemaless.schema['Bike'][:attr_schema]['cc']).to eq(:integer)
44
+ # end
45
+ end
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'Schemaless' do
5
+
6
+ it 'should get all models`s fields' do
7
+ expect(Bike.schemaless_indexes).to be_an(Array)
8
+ end
9
+
10
+ it 'should get all models`s fields' do
11
+ # bike_model = { 'Bike' => { cc: String } }
12
+ expect(Bike.schemaless_indexes.map(&:fields)).to include(:cc)
13
+ end
14
+
15
+ it 'should respond to schemaless' do
16
+ expect(ActiveRecord::Base).to respond_to :index
17
+ end
18
+
19
+ it 'should get current indexes' do
20
+ expect(User.current_indexes).to be_an(Array)
21
+ end
22
+
23
+ # u = User.create(name: 'Bob', other: :bar, status: :inactive, cool: false)
24
+ # expect(u.errors.messages).to be_blank
25
+ # end
26
+
27
+ # it 'should work fine on create' do
28
+ # u = User.create(name: 'Bob')
29
+ # expect(User.count).to eq 1
30
+ # end
31
+
32
+ # it 'should get all models`s fields' do
33
+ # expect(Schemaless.schema['User'][:index_db]).to be_an(Array)
34
+ # end
35
+
36
+ # it 'should get all models`s fields' do
37
+ # expect(Schemaless.schema['User'][:index_schema]).to be_an(Array)
38
+ # end
39
+
40
+ # it 'should get all models`s fields' do
41
+ # expect(Schemaless.schema['User'][:index_schema]).to eq([])
42
+ # end
43
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Field' do
4
+
5
+ it 'should have a name' do
6
+ expect(Schemaless::Field.new('cc', Integer).name).to eq('cc')
7
+ end
8
+
9
+ it 'should have a type' do
10
+ expect(Schemaless::Field.new('cc', Integer).type).to eq(:integer)
11
+ end
12
+
13
+ describe 'Field mapping' do
14
+
15
+ it 'should map field integer' do
16
+ expect(Schemaless::Field.new('cc', Integer).type).to eq(:integer)
17
+ end
18
+
19
+ it 'should map field decimal' do
20
+ expect(Schemaless::Field.new('cc', BigDecimal).type).to eq(:decimal)
21
+ end
22
+
23
+ it 'should map field float' do
24
+ expect(Schemaless::Field.new('cc', Float).type).to eq(:float)
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Schemaless::Index' do
4
+
5
+ it 'should instantiate' do
6
+ expect { Schemaless::Index.new(:foo) }.to_not raise_error
7
+ end
8
+
9
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Schemaless::Table' do
4
+
5
+ before do
6
+ @app = ::ActiveRecord::Base.descendants
7
+ end
8
+
9
+ it 'should instantiate' do
10
+ expect { Schemaless::Table.new(@app.last) }.to_not raise_error
11
+ end
12
+
13
+ # it "should create tables nice" do
14
+ # expect(Schemaless::Table.new(@app.last)).to include(Bike)
15
+ # end
16
+
17
+ it 'should create tables nice' do
18
+ expect(Schemaless::Table.new(@app[1]).model).to eq(Place)
19
+ end
20
+
21
+ it 'should create tables nice' do
22
+ expect(Schemaless::Table.new(@app[1]).name).to eq('places')
23
+ end
24
+
25
+ end
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'Schemaless::Worker' do
5
+
6
+ it 'should create cc on bikes' do
7
+ Schemaless::Worker.run!
8
+ expect { Bike.create!(name: 'Gina', cc: 600) }.to_not raise_error
9
+ expect(Bike.count).to eq(1)
10
+ end
11
+
12
+ it 'should re-run nicely' do
13
+ Schemaless::Worker.run!
14
+ Schemaless::Worker.run!
15
+ expect { Bike.create!(name: 'Gina', cc: 600) }.to_not raise_error
16
+ expect(Bike.count).to eq(1)
17
+ end
18
+
19
+ it 'should work in sandbox mode' do
20
+ Schemaless.sandbox = true
21
+ Schemaless::Worker.run!
22
+ expect { Bike.create!(name: 'Gina', cc: 600) }.to raise_error
23
+ expect(Bike.count).to be_zero
24
+ end
25
+
26
+ it 'should create a foreign key with belongs_to' do
27
+ Schemaless::Worker.run!
28
+ user = User.create!(name: 'Lemmy')
29
+ expect { Bike.create(name: 'Dark', user: user) }.to_not raise_error
30
+ end
31
+
32
+ describe 'Field creation' do
33
+
34
+ it 'should create table if inexistant' do
35
+ # ActiveRecord::Migration.drop_table(:bikes)
36
+ Schemaless::Worker.run!
37
+ expect { Bike.create!(name: 'Gina', cc: 600) }.to_not raise_error
38
+ expect(Bike.count).to eq(1)
39
+ end
40
+
41
+ end
42
+
43
+ describe 'Migrations' do
44
+
45
+ it 'should create migration files' do
46
+ pending
47
+ Schemaless::Worker.generate!
48
+ expect(File.exist?('spec/dummy/db/migrate/fu')).to eq(true)
49
+ end
50
+
51
+ it 'should not touch database schema version' do
52
+ expect { Schemaless::Worker.run! }
53
+ .to_not change(ActiveRecord::Migrator, :get_all_versions)
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'Schemaless' do
5
+
6
+ it 'should get all models`s fields' do
7
+ expect(Schemaless).to be_an(Module)
8
+ end
9
+
10
+ it 'should have a sandbox mode' do
11
+ Schemaless.sandbox = true
12
+ expect(Schemaless.sandbox).to eq(true)
13
+ end
14
+
15
+ end
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ # require 'pry'
3
+ begin
4
+ require 'spec'
5
+ rescue LoadError
6
+ require 'rspec'
7
+ end
8
+
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+ ENV['RAILS_ENV'] ||= 'test'
12
+
13
+ require 'rails'
14
+ require 'active_record'
15
+ puts "Using ActiveRecord #{ActiveRecord::VERSION::STRING}"
16
+
17
+ require 'schemaless' # /active_record'
18
+ # ActiveRecord::Base.send :include, Schemaless::Fields
19
+
20
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
21
+ # require 'i18n'
22
+ require 'rspec/rails'
23
+
24
+ Rails.backtrace_cleaner.remove_silencers!
25
+
26
+ # I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'locales', '*.yml')]
27
+ # I18n.default_locale = 'pt'
28
+
29
+ # Load support files
30
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
31
+
32
+ if ENV['CI']
33
+ require 'coveralls'
34
+ Coveralls.wear!
35
+ end
36
+
37
+ Rails.application.eager_load!
38
+
39
+ RSpec.configure do |config|
40
+
41
+ config.mock_with :rspec
42
+ config.use_transactional_fixtures = true
43
+ config.infer_base_class_for_anonymous_controllers = false
44
+ config.order = 'random'
45
+
46
+ config.before(:each) do
47
+ [:users, :bikes, :places, :user_skills, :user_extras].each do |db|
48
+ ActiveRecord::Migration.drop_table(db) rescue nil # rubocop:disable Style/RescueModifier
49
+ end
50
+ CreateTestingStructure.new.change
51
+ Schemaless.sandbox = nil
52
+ end
53
+
54
+ config.after(:each) do
55
+ end
56
+
57
+ end
@@ -0,0 +1,36 @@
1
+ # rubocop:disable all
2
+ class CreateTestingStructure < ActiveRecord::Migration
3
+ def change
4
+ create_table :users do |t|
5
+ t.string :name, :other, :language
6
+ t.string :status, default: :active
7
+ t.string :limited, limit: 10
8
+ t.boolean :sex
9
+ t.boolean :public
10
+ t.boolean :cool
11
+ t.integer :number
12
+ end
13
+ add_index :users, :sex
14
+ add_index :users, :name
15
+ add_index :users, [:number, :status]
16
+
17
+ create_table :user_skills do |t|
18
+ t.references :user
19
+ t.string :kind
20
+ end
21
+
22
+ create_table :user_extras do |t|
23
+ t.references :user
24
+ t.string :key, null: false
25
+ end
26
+
27
+ create_table :bikes do |t|
28
+ t.string :name, null: false
29
+ t.integer :cylinders
30
+ end
31
+
32
+ create_table :places do |t|
33
+ t.string :name, null: false
34
+ end
35
+ end
36
+ end