Skip to content
This repository

When generating a model/migration from cli added ability to specify whether particular property should also have an index #2555

Closed
wants to merge 5 commits into from

7 participants

Dmitrii Samoilov Alexey Muranov Prem Sichanugrist Damien Mathieu Gavin Morrice José Valim Vijay Dev
Dmitrii Samoilov

When generating a model/migration from cli wouldn't that be nice if there would be an ability to specify whether particular property should also have an index like this:

rails g model person name:string:index profile:string

so developer could just run 'rake db:migrate' w/o looking into migration file?

The main change is adding the has_index property in the railties/lib/rails/generators/generated_attribute.rb:

module Rails
  module Generators
    class GeneratedAttribute
      attr_accessor :name, :type, :has_index

      def initialize(name, type, has_index = false)
        type = :string if type.blank?
        @name, @type, @has_index = name, type.to_sym, has_index.eql?("index")
      end

      ...

      def has_index?
        @has_index
      end
    end
  end
end

What do you think of it? Was it worth implementing?

UPD: added ability to specify :limit and :precision/:scale column options in migration like this: name:string[40] or name:string[40]:index or price:decimal[5.2] as proposed below (I chosen square brackets because parentheses break bash shell)

UPD changed a dot to a comma and square brackets to curly ones while specifying column type options

Dmitrii Samoilov added ability to specify from cli when generating a model/migration w…
…hether particular property should be an index like this 'rails g model person name:string:index profile:string'
3d2eed7
railties/lib/rails/generators/named_base.rb
@@ -154,8 +154,8 @@ module Rails
154 154
         # Convert attributes array into GeneratedAttribute objects.
155 155
         def parse_attributes! #:nodoc:
156 156
           self.attributes = (attributes || []).map do |key_value|
157  
-            name, type = key_value.split(':')
158  
-            Rails::Generators::GeneratedAttribute.new(name, type)
  157
+            name, type, has_index = key_value.split(':')
7
Vijay Dev Collaborator
vijaydev added a note August 17, 2011

Rails 3.2 (edge) has a change where the type can be omitted and it will default to string. So you need to support "name:index" in addition to "name:string:index".

Vijay Dev Collaborator
vijaydev added a note August 17, 2011

Here is the relevant commit: 08983fe

Dmitrii Samoilov
german added a note August 17, 2011

yes, I see

Dmitrii Samoilov
german added a note August 17, 2011

fixed in german@12dcac7

José Valim Owner

What if we remove this code from here and move it to Rails::Generators::GeneratedAttribute.parse(key_value). That said, the responsibility ends up all in one place.

Dmitrii Samoilov
german added a note December 23, 2011

You mean move this code to Rails::Generators::GeneratedAttribute#parse(key_value):

   name, type, has_index = key_value.split(':')
   # if user provided "name:index" instead of "name:string:index" type should be set blank
   # so GeneratedAttribute's constructor could set it to :string
   if type.eql?("index")
     has_index = type
     type = nil
   end

So we could write Rails::Generators::GeneratedAttribute.parse(key_value) ? Sure, I think it's ok.

José Valim Owner
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Dmitrii Samoilov added condition to check whether user omitted type of the attribute b…
…ut specified it should have index while generating model/migration from the cli, so 'rails g model person name:index age:integer' should work
12dcac7
Alexey Muranov

I like the idea. It would also be nice to be able to specify the length as name:string(40).

Dmitrii Samoilov

@alexeymuranov yeah, I didn't thought of that. Will try to implement it.

Dmitrii Samoilov

@alexeymuranov I think that's what you've talked about: name:string[40] or name:string[40]:index or price:decimal[5.2]. I choose square brackets because parentheses break bash shell

Alexey Muranov

Thanks!

Prem Sichanugrist
Collaborator

Square brackets need to be escaped in zsh as well ...

Dmitrii Samoilov

Thanks for the feedback @sikachu. So what do you think of which delimiter will do ideally? Comma maybe (like "name:string,20") or curly brackets (like "name:string{20}:index") or dot? Or should I delete the last commit at all?

Alexey Muranov

Sorry for starting this :). Maybe underscore? name:string_20:index
Or just name:string20:index

Damien Mathieu
Collaborator

Is this really useful ? I don't think a lot of people will use it, it's too hard to remember.
And when you want to create a really specific migration with specific indexes, you can still manually edit the file.

Alexey Muranov

About the parentheses: i thought that the parentheses syntax was natural, and this is how annotate_models writes its comments, but if parentheses do not work in bash, i do not know.
In my opinion, there is some use in all this: it is easier to edit several command lines before pasting them into the shell, than edit multiple migration files afterwards.

Dmitrii Samoilov

@dmathieu well, I don't know about :limit/:precision/:scale options but at least :index option might be useful, I often add indices by myself after generating a migration and I thought it could be automated somehow.

Gavin Morrice

Just noticed this pull request
+1 - great idea

Alexey Muranov

@german, just a thought: use parenthesis () for :limit, and those who need them from the command line, like me, will escape them!

Dmitrii Samoilov

@alexeymuranov I think I'll better create a thread in rails-core google group, so this pull request could attract more attention and gather some more opinions
/ cc @spastorino

Dmitrii Samoilov german closed this November 24, 2011
Dmitrii Samoilov german reopened this December 15, 2011
railties/lib/rails/generators/generated_attribute.rb
((9 lines not shown))
10 10
         type = :string if type.blank?
11  
-        @name, @type = name, type.to_sym
  11
+        @name, @type, @attr_options, @has_index = name, *parse_type_and_options(type), has_index.eql?("index")
2
José Valim Owner

We don't need to do everything in one line. :)

Dmitrii Samoilov
german added a note December 23, 2011

yes, I know)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
José Valim josevalim commented on the diff December 23, 2011
activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
@@ -3,7 +3,7 @@
3 3
 module ActiveRecord
4 4
   module Generators
5 5
     class MigrationGenerator < Base
6  
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
  6
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
3
José Valim Owner

Let's change the banner to: "field field:type field:type:index". What do you think?

Dmitrii Samoilov
german added a note December 23, 2011

Ok, cool. Actually I'm in doubt whether 'name:string[40]' functionality is needed as it was proposed ealier #2555 (comment) ? what do you think?

José Valim Owner

I think it would be too hard to put all this information in the banner. We should document it in the USAGE though. Now that we use {} for extra information, we could even change the banner to: field[:type][:index] field[:type][:index] and put the remaining information in the USAGE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
José Valim
Owner

I like [] because this is what rake uses.

José Valim
Owner

Btw, decimal[5.2] meaning precision.scale is not good. I would suggest using decimal[5,2] or removing it.

railties/lib/rails/generators/generated_attribute.rb
@@ -48,6 +48,27 @@ def human_name
48 48
       def reference?
49 49
         self.type.in?([:references, :belongs_to])
50 50
       end
  51
+      
  52
+      def has_index?
  53
+        @has_index
  54
+      end
  55
+
  56
+      # parse possible attribute options like :limit for string/text/binary/integer or :precision/:scale for decimals
  57
+      # when declaring options square brackets should be used since bash interpreter fails when parentheses are used
  58
+      def parse_type_and_options(type)
1
José Valim Owner

As I said, this could be the class method parse and the object would be then initialized with all four args (name, type, index and options).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Dmitrii Samoilov changed square brackets to curly ones in column type definition, also…
… added ability to specify (uniq|unique) in index definition, so now it's possible to write 'discount:decimal{5,2}:uniq' or 'user_uuid:uniq' while generating new model/migration
51eded9
Dmitrii Samoilov

I've

  • changed square brackets to the curly ones in column type definition (so zsh and bash are ok)
  • changed a dot to a comma
  • added ability to specify (uniq|unique) in column definition (instead of index)

so now it's possible to write 'discount:decimal{5,2}:unique' or 'user_uuid:uniq' while generating new model/migration.

What do you think of this? I'll investigate on this further tomorrow. Thanks.

José Valim
Owner

I have merged this to a local branch. I will push it to master soon.

José Valim josevalim closed this pull request from a commit December 24, 2011
José Valim Merge branch 'gzip-index' which contains two features:
1) Adding gzip to pages cache, closes #4124

2) Allow scaffold/model/migration generators to accept a "index" and "uniq"
modifiers, as in: "tracking_id:integer:uniq" in order to generate (unique)
indexes. Some types also accept custom options, for instance, you can
specify the precision and scale for decimals as "price:decimal{7,2}".
This feature closes #2555.
0152fe9
José Valim josevalim closed this in 0152fe9 December 24, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 5 unique commits by 2 authors.

Aug 17, 2011
Dmitrii Samoilov added ability to specify from cli when generating a model/migration w…
…hether particular property should be an index like this 'rails g model person name:string:index profile:string'
3d2eed7
Dmitrii Samoilov added condition to check whether user omitted type of the attribute b…
…ut specified it should have index while generating model/migration from the cli, so 'rails g model person name:index age:integer' should work
12dcac7
Sep 02, 2011
Dmitrii Samoilov added ability to specify :limit and :precision/:scale column options …
…in migration from cli
4e47df7
Nov 28, 2011
Merge branch 'master' of git://github.com/rails/rails dc6c674
Dec 23, 2011
Dmitrii Samoilov changed square brackets to curly ones in column type definition, also…
… added ability to specify (uniq|unique) in index definition, so now it's possible to write 'discount:decimal{5,2}:uniq' or 'user_uuid:uniq' while generating new model/migration
51eded9
This page is out of date. Refresh to see the latest.
2  activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
@@ -3,7 +3,7 @@
3 3
 module ActiveRecord
4 4
   module Generators
5 5
     class MigrationGenerator < Base
6  
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
  6
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
7 7
 
8 8
       def create_migration_file
9 9
         set_local_assigns!
12  activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
@@ -2,14 +2,20 @@ class <%= migration_class_name %> < ActiveRecord::Migration
2 2
 <%- if migration_action == 'add' -%>
3 3
   def change
4 4
 <% attributes.each do |attribute| -%>
5  
-    add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %>
  5
+    add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
  6
+    <%- if attribute.has_index? -%>
  7
+    add_index :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_index_options %>
  8
+    <%- end %>
6 9
 <%- end -%>
7 10
   end
8 11
 <%- else -%>
9 12
   def up
10 13
 <% attributes.each do |attribute| -%>
11 14
   <%- if migration_action -%>
12  
-    <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end %>
  15
+    <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
  16
+    <% if attribute.has_index? && migration_action == 'add' %>
  17
+    add_index :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_index_options %>
  18
+    <% end -%>
13 19
   <%- end -%>
14 20
 <%- end -%>
15 21
   end
@@ -17,7 +23,7 @@ def up
17 23
   def down
18 24
 <% attributes.reverse.each do |attribute| -%>
19 25
   <%- if migration_action -%>
20  
-    <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end %>
  26
+    <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
21 27
   <%- end -%>
22 28
 <%- end -%>
23 29
   end
2  activerecord/lib/rails/generators/active_record/model/model_generator.rb
@@ -3,7 +3,7 @@
3 3
 module ActiveRecord
4 4
   module Generators
5 5
     class ModelGenerator < Base
6  
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
  6
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
7 7
 
8 8
       check_class_collision
9 9
 
7  activerecord/lib/rails/generators/active_record/model/templates/migration.rb
@@ -2,7 +2,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration
2 2
   def change
3 3
     create_table :<%= table_name %> do |t|
4 4
 <% attributes.each do |attribute| -%>
5  
-      t.<%= attribute.type %> :<%= attribute.name %>
  5
+      t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
6 6
 <% end -%>
7 7
 <% if options[:timestamps] %>
8 8
       t.timestamps
@@ -10,8 +10,11 @@ def change
10 10
     end
11 11
 <% if options[:indexes] -%>
12 12
 <% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
13  
-    add_index :<%= table_name %>, :<%= attribute.name %>_id
  13
+    add_index :<%= table_name %>, :<%= attribute.name %>_id<%= attribute.inject_index_options %>
14 14
 <% end -%>
15 15
 <% end -%>
  16
+<% attributes.select {|attr| attr.has_index? }.each do |attribute| -%>
  17
+    add_index :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_index_options %>
  18
+<% end -%>
16 19
   end
17 20
 end
52  railties/lib/rails/generators/generated_attribute.rb
@@ -4,11 +4,10 @@
4 4
 module Rails
5 5
   module Generators
6 6
     class GeneratedAttribute
7  
-      attr_accessor :name, :type
  7
+      attr_accessor :name, :type, :has_index, :attr_options
8 8
 
9  
-      def initialize(name, type)
10  
-        type = :string if type.blank?
11  
-        @name, @type = name, type.to_sym
  9
+      def initialize(column_definition)
  10
+        parse column_definition
12 11
       end
13 12
 
14 13
       def field_type
@@ -48,6 +47,51 @@ def human_name
48 47
       def reference?
49 48
         self.type.in?([:references, :belongs_to])
50 49
       end
  50
+      
  51
+      def has_index?
  52
+        @has_index
  53
+      end
  54
+
  55
+      def has_uniq_index?
  56
+        @has_uniq_index
  57
+      end
  58
+
  59
+      def parse(column_definition)
  60
+        name, type, has_index = column_definition.split(':')
  61
+        # if user provided "name:index" instead of "name:string:index" type should be set blank
  62
+        # so GeneratedAttribute's constructor could set it to :string
  63
+        if type =~ /index|uniq|unique/i
  64
+          has_index = type
  65
+          type = nil
  66
+        end
  67
+        type = :string if type.blank?
  68
+
  69
+        @name = name
  70
+        @type, @attr_options = *parse_type_and_options(type)
  71
+        @has_index = ['index','uniq','unique'].include?(has_index)
  72
+        @has_uniq_index = ['uniq','unique'].include?(has_index)
  73
+      end
  74
+
  75
+      # parse possible attribute options like :limit for string/text/binary/integer or :precision/:scale for decimals
  76
+      # when declaring options curly brackets should be used
  77
+      def parse_type_and_options(type)
  78
+        attribute_options = case type 
  79
+          when /(string|text|binary|integer){(\d+)}/
  80
+            {:limit => $2.to_i}
  81
+          when /decimal{(\d+),(\d+)}/
  82
+            {:precision => $1.to_i, :scale => $2.to_i}
  83
+          else; {}
  84
+        end
  85
+        [type.to_s.gsub(/{.*}/,'').to_sym, attribute_options]
  86
+      end
  87
+
  88
+      def inject_options
  89
+        @attr_options.blank? ? '' : ", #{@attr_options.to_s.gsub(/[{}]/, '')}"
  90
+      end
  91
+
  92
+      def inject_index_options
  93
+        has_uniq_index? ? ", :unique => true" : ''
  94
+      end
51 95
     end
52 96
   end
53 97
 end
5  railties/lib/rails/generators/named_base.rb
@@ -153,9 +153,8 @@ def assign_names!(name) #:nodoc:
153 153
 
154 154
         # Convert attributes array into GeneratedAttribute objects.
155 155
         def parse_attributes! #:nodoc:
156  
-          self.attributes = (attributes || []).map do |key_value|
157  
-            name, type = key_value.split(':')
158  
-            Rails::Generators::GeneratedAttribute.new(name, type)
  156
+          self.attributes = (attributes || []).map do |attr|
  157
+            Rails::Generators::GeneratedAttribute.new(attr)
159 158
           end
160 159
         end
161 160
 
2  railties/lib/rails/generators/rails/migration/migration_generator.rb
... ...
@@ -1,7 +1,7 @@
1 1
 module Rails
2 2
   module Generators
3 3
     class MigrationGenerator < NamedBase #metagenerator
4  
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
  4
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
5 5
       hook_for :orm, :required => true
6 6
     end
7 7
   end
2  railties/lib/rails/generators/rails/model/model_generator.rb
... ...
@@ -1,7 +1,7 @@
1 1
 module Rails
2 2
   module Generators
3 3
     class ModelGenerator < NamedBase #metagenerator
4  
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
  4
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
5 5
       hook_for :orm, :required => true
6 6
     end
7 7
   end
2  railties/lib/rails/generators/test_case.rb
@@ -219,7 +219,7 @@ def generator(args=self.default_arguments, options={}, config={})
219 219
       #   create_generated_attribute(:string, 'name')
220 220
       #
221 221
       def create_generated_attribute(attribute_type, name = 'test')
222  
-        Rails::Generators::GeneratedAttribute.new(name, attribute_type.to_s)
  222
+        Rails::Generators::GeneratedAttribute.new([name, attribute_type.to_s].join(':'))
223 223
       end
224 224
 
225 225
       protected
2  railties/test/generators/generated_attribute_test.rb
@@ -69,7 +69,7 @@ def test_default_value_is_string
69 69
   end
70 70
 
71 71
   def test_default_value_for_type
72  
-    att = Rails::Generators::GeneratedAttribute.new("type", "string")
  72
+    att = Rails::Generators::GeneratedAttribute.new("type:string")
73 73
     assert_equal("", att.default)
74 74
   end
75 75
 
62  railties/test/generators/migration_generator_test.rb
@@ -58,6 +58,68 @@ def test_remove_migration_with_attributes
58 58
     end
59 59
   end
60 60
 
  61
+  def test_add_migration_with_attributes_and_indices
  62
+    migration = "add_title_with_index_and_body_to_posts"
  63
+    run_generator [migration, "title:string:index", "body:text", "user_id:integer:unique"]
  64
+
  65
+    assert_migration "db/migrate/#{migration}.rb" do |content|
  66
+      assert_method :change, content do |up|
  67
+        assert_match(/add_column :posts, :title, :string/, up)
  68
+        assert_match(/add_column :posts, :body, :text/, up)
  69
+        assert_match(/add_column :posts, :user_id, :integer/, up)
  70
+      end
  71
+      assert_match(/add_index :posts, :title/, content)
  72
+      assert_match(/add_index :posts, :user_id, :unique => true/, content)
  73
+    end
  74
+  end
  75
+
  76
+  def test_add_migration_with_attributes_and_wrong_index_declaration
  77
+    migration = "add_title_and_content_to_books"
  78
+    run_generator [migration, "title:string:inex", "content:text", "user_id:integer:unik"]
  79
+
  80
+    assert_migration "db/migrate/#{migration}.rb" do |content|
  81
+      assert_method :change, content do |up|
  82
+        assert_match(/add_column :books, :title, :string/, up)
  83
+        assert_match(/add_column :books, :content, :text/, up)
  84
+        assert_match(/add_column :books, :user_id, :integer/, up)
  85
+      end
  86
+      assert_not_match(/add_index :books, :title/, content)
  87
+      assert_not_match(/add_index :books, :user_id/, content)
  88
+    end
  89
+  end
  90
+
  91
+  def test_add_migration_with_attributes_without_type_and_index
  92
+    migration = "add_title_with_index_and_body_to_posts"
  93
+    run_generator [migration, "title:index", "body:text", "user_uuid:uniq"]
  94
+
  95
+    assert_migration "db/migrate/#{migration}.rb" do |content|
  96
+      assert_method :change, content do |up|
  97
+        assert_match(/add_column :posts, :title, :string/, up)
  98
+        assert_match(/add_column :posts, :body, :text/, up)
  99
+        assert_match(/add_column :posts, :user_uuid, :string/, up)
  100
+      end
  101
+      assert_match(/add_index :posts, :title/, content)
  102
+      assert_match(/add_index :posts, :user_uuid, :unique => true/, content)
  103
+    end
  104
+  end
  105
+
  106
+  def test_add_migration_with_attributes_index_declaration_and_attribute_options
  107
+    migration = "add_title_and_content_to_books"
  108
+    run_generator [migration, "title:string{40}:index", "content:string{255}", "price:decimal{5,2}:index", "discount:decimal{3,2}:uniq"]
  109
+
  110
+    assert_migration "db/migrate/#{migration}.rb" do |content|
  111
+      assert_method :change, content do |up|
  112
+        assert_match(/add_column :books, :title, :string, :limit=>40/, up)
  113
+        assert_match(/add_column :books, :content, :string, :limit=>255/, up)
  114
+        assert_match(/add_column :books, :price, :decimal, :precision=>5, :scale=>2/, up)
  115
+        assert_match(/add_column :books, :discount, :decimal, :precision=>3, :scale=>2/, up)
  116
+      end
  117
+      assert_match(/add_index :books, :title/, content)
  118
+      assert_match(/add_index :books, :price/, content)
  119
+      assert_match(/add_index :books, :discount, :unique => true/, content)
  120
+    end
  121
+  end
  122
+
61 123
   def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
62 124
     migration = "create_books"
63 125
     run_generator [migration, "title:string", "content:text"]
68  railties/test/generators/model_generator_test.rb
@@ -113,6 +113,74 @@ def test_migration_with_attributes
113 113
     end
114 114
   end
115 115
 
  116
+  def test_migration_with_attributes_and_with_index
  117
+    run_generator ["product", "name:string:index", "supplier_id:integer:index", "user_id:integer:uniq", "order_id:unique"]
  118
+
  119
+    assert_migration "db/migrate/create_products.rb" do |m|
  120
+      assert_method :change, m do |up|
  121
+        assert_match(/create_table :products/, up)
  122
+        assert_match(/t\.string :name/, up)
  123
+        assert_match(/t\.integer :supplier_id/, up)
  124
+        assert_match(/t\.integer :user_id/, up)
  125
+        assert_match(/t\.string :order_id/, up)
  126
+
  127
+        assert_match(/add_index :products, :name/, up)
  128
+        assert_match(/add_index :products, :supplier_id/, up)
  129
+        assert_match(/add_index :products, :user_id, :unique => true/, up)
  130
+        assert_match(/add_index :products, :order_id, :unique => true/, up)
  131
+      end
  132
+    end
  133
+  end
  134
+
  135
+  def test_migration_with_attributes_and_with_wrong_index_declaration
  136
+    run_generator ["product", "name:string", "supplier_id:integer:inex", "user_id:integer:unqu"]
  137
+
  138
+    assert_migration "db/migrate/create_products.rb" do |m|
  139
+      assert_method :change, m do |up|
  140
+        assert_match(/create_table :products/, up)
  141
+        assert_match(/t\.string :name/, up)
  142
+        assert_match(/t\.integer :supplier_id/, up)
  143
+        assert_match(/t\.integer :user_id/, up)
  144
+
  145
+        assert_not_match(/add_index :products, :name/, up)
  146
+        assert_not_match(/add_index :products, :supplier_id/, up)
  147
+        assert_not_match(/add_index :products, :user_id/, up)
  148
+      end
  149
+    end
  150
+  end
  151
+
  152
+  def test_migration_with_missing_attribute_type_and_with_index
  153
+    run_generator ["product", "name:index", "supplier_id:integer:index", "year:integer"]
  154
+
  155
+    assert_migration "db/migrate/create_products.rb" do |m|
  156
+      assert_method :change, m do |up|
  157
+        assert_match(/create_table :products/, up)
  158
+        assert_match(/t\.string :name/, up)
  159
+        assert_match(/t\.integer :supplier_id/, up)
  160
+        
  161
+        assert_match(/add_index :products, :name/, up)
  162
+        assert_match(/add_index :products, :supplier_id/, up)
  163
+        assert_not_match(/add_index :products, :year/, up)
  164
+      end
  165
+    end
  166
+  end
  167
+
  168
+  def test_add_migration_with_attributes_index_declaration_and_attribute_options
  169
+    run_generator ["product", "title:string{40}:index", "content:string{255}", "price:decimal{5,2}:index", "discount:decimal{5,2}:uniq"]
  170
+
  171
+    assert_migration "db/migrate/create_products.rb" do |content|
  172
+      assert_method :change, content do |up|
  173
+        assert_match(/create_table :products/, up)
  174
+        assert_match(/t.string :title, :limit=>40/, up)
  175
+        assert_match(/t.string :content, :limit=>255/, up)
  176
+        assert_match(/t.decimal :price, :precision=>5, :scale=>2/, up)
  177
+      end
  178
+      assert_match(/add_index :products, :title/, content)
  179
+      assert_match(/add_index :products, :price/, content)
  180
+      assert_match(/add_index :products, :discount, :unique => true/, content)
  181
+    end
  182
+  end
  183
+  
116 184
   def test_migration_without_timestamps
117 185
     ActiveRecord::Base.timestamped_migrations = false
118 186
     run_generator ["account"]
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.