From 7f5b51686c556e3a35a2e5320fe8e4d758ff70b5 Mon Sep 17 00:00:00 2001
From: Dmitrii Samoilov <e2718281828@ya.ru>
Date: Wed, 17 Aug 2011 12:16:04 +0300
Subject: added ability to specify from cli when generating a model/migration
 whether particular property should be an index like this 'rails g model
 person name:string:index profile:string'

---
 .../lib/rails/generators/generated_attribute.rb    | 52 ++++++++++++++++++++--
 railties/lib/rails/generators/named_base.rb        |  5 +--
 .../rails/migration/migration_generator.rb         |  2 +-
 .../generators/rails/model/model_generator.rb      |  2 +-
 railties/lib/rails/generators/test_case.rb         |  2 +-
 5 files changed, 53 insertions(+), 10 deletions(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb
index 816d82cac3..5ba37737a2 100644
--- a/railties/lib/rails/generators/generated_attribute.rb
+++ b/railties/lib/rails/generators/generated_attribute.rb
@@ -4,11 +4,10 @@ require 'active_support/core_ext/object/inclusion'
 module Rails
   module Generators
     class GeneratedAttribute
-      attr_accessor :name, :type
+      attr_accessor :name, :type, :has_index, :attr_options
 
-      def initialize(name, type)
-        type = :string if type.blank?
-        @name, @type = name, type.to_sym
+      def initialize(column_definition)
+        parse column_definition
       end
 
       def field_type
@@ -48,6 +47,51 @@ module Rails
       def reference?
         self.type.in?([:references, :belongs_to])
       end
+      
+      def has_index?
+        @has_index
+      end
+
+      def has_uniq_index?
+        @has_uniq_index
+      end
+
+      def parse(column_definition)
+        name, type, has_index = column_definition.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 =~ /index|uniq|unique/i
+          has_index = type
+          type = nil
+        end
+        type = :string if type.blank?
+
+        @name = name
+        @type, @attr_options = *parse_type_and_options(type)
+        @has_index = ['index','uniq','unique'].include?(has_index)
+        @has_uniq_index = ['uniq','unique'].include?(has_index)
+      end
+
+      # parse possible attribute options like :limit for string/text/binary/integer or :precision/:scale for decimals
+      # when declaring options curly brackets should be used
+      def parse_type_and_options(type)
+        attribute_options = case type 
+          when /(string|text|binary|integer){(\d+)}/
+            {:limit => $2.to_i}
+          when /decimal{(\d+),(\d+)}/
+            {:precision => $1.to_i, :scale => $2.to_i}
+          else; {}
+        end
+        [type.to_s.gsub(/{.*}/,'').to_sym, attribute_options]
+      end
+
+      def inject_options
+        @attr_options.blank? ? '' : ", #{@attr_options.to_s.gsub(/[{}]/, '')}"
+      end
+
+      def inject_index_options
+        has_uniq_index? ? ", :unique => true" : ''
+      end
     end
   end
 end
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index c6c0392f43..980d6068e3 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -153,9 +153,8 @@ module Rails
 
         # Convert attributes array into GeneratedAttribute objects.
         def parse_attributes! #:nodoc:
-          self.attributes = (attributes || []).map do |key_value|
-            name, type = key_value.split(':')
-            Rails::Generators::GeneratedAttribute.new(name, type)
+          self.attributes = (attributes || []).map do |attr|
+            Rails::Generators::GeneratedAttribute.new(attr)
           end
         end
 
diff --git a/railties/lib/rails/generators/rails/migration/migration_generator.rb b/railties/lib/rails/generators/rails/migration/migration_generator.rb
index 39fa5b63b1..ecf0a77b76 100644
--- a/railties/lib/rails/generators/rails/migration/migration_generator.rb
+++ b/railties/lib/rails/generators/rails/migration/migration_generator.rb
@@ -1,7 +1,7 @@
 module Rails
   module Generators
     class MigrationGenerator < NamedBase #metagenerator
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
       hook_for :orm, :required => true
     end
   end
diff --git a/railties/lib/rails/generators/rails/model/model_generator.rb b/railties/lib/rails/generators/rails/model/model_generator.rb
index 629d5eed3f..2a882981c3 100644
--- a/railties/lib/rails/generators/rails/model/model_generator.rb
+++ b/railties/lib/rails/generators/rails/model/model_generator.rb
@@ -1,7 +1,7 @@
 module Rails
   module Generators
     class ModelGenerator < NamedBase #metagenerator
-      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
+      argument :attributes, :type => :array, :default => [], :banner => "field:type field:type field:type:index"
       hook_for :orm, :required => true
     end
   end
diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb
index 7319fb79f6..ab55031d07 100644
--- a/railties/lib/rails/generators/test_case.rb
+++ b/railties/lib/rails/generators/test_case.rb
@@ -219,7 +219,7 @@ module Rails
       #   create_generated_attribute(:string, 'name')
       #
       def create_generated_attribute(attribute_type, name = 'test')
-        Rails::Generators::GeneratedAttribute.new(name, attribute_type.to_s)
+        Rails::Generators::GeneratedAttribute.new([name, attribute_type.to_s].join(':'))
       end
 
       protected
-- 
cgit v1.2.3