Skip to content
This repository
tag: v3.2.9.rc1
Fetching contributors…

Cannot retrieve contributors at this time

file 202 lines (167 sloc) 6.064 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
require 'active_support/core_ext/module/introspection'
require 'rails/generators/base'
require 'rails/generators/generated_attribute'

module Rails
  module Generators
    class NamedBase < Base
      argument :name, :type => :string
      class_option :skip_namespace, :type => :boolean, :default => false,
                                    :desc => "Skip namespace (affects only isolated applications)"

      class_option :old_style_hash, :type => :boolean, :default => false,
                                    :desc => "Force using old style hash (:foo => 'bar') on Ruby >= 1.9"

      def initialize(args, *options) #:nodoc:
        @inside_template = nil
        # Unfreeze name in case it's given as a frozen string
        args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
        super
        assign_names!(self.name)
        parse_attributes! if respond_to?(:attributes)
      end

      no_tasks do
        def template(source, *args, &block)
          inside_template do
            super
          end
        end
      end

      protected
        attr_reader :file_name
        alias :singular_name :file_name

        # Wrap block with namespace of current application
        # if namespace exists and is not skipped
        def module_namespacing(&block)
          content = capture(&block)
          content = wrap_with_namespace(content) if namespaced?
          concat(content)
        end

        def indent(content, multiplier = 2)
          spaces = " " * multiplier
          content = content.each_line.map {|line| "#{spaces}#{line}" }.join
        end

        def wrap_with_namespace(content)
          content = indent(content).chomp
          "module #{namespace.name}\n#{content}\nend\n"
        end

        def inside_template
          @inside_template = true
          yield
        ensure
          @inside_template = false
        end

        def inside_template?
          @inside_template
        end

        def namespace
          Rails::Generators.namespace
        end

        def namespaced?
          !options[:skip_namespace] && namespace
        end

        def file_path
          @file_path ||= (class_path + [file_name]).join('/')
        end

        def class_path
          inside_template? || !namespaced? ? regular_class_path : namespaced_class_path
        end

        def regular_class_path
          @class_path
        end

        def namespaced_file_path
          @namespaced_file_path ||= namespaced_class_path.join("/")
        end

        def namespaced_class_path
          @namespaced_class_path ||= begin
            namespace_path = namespace.name.split("::").map {|m| m.underscore }
            namespace_path + @class_path
          end
        end

        def class_name
          (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
        end

        def human_name
          @human_name ||= singular_name.humanize
        end

        def plural_name
          @plural_name ||= singular_name.pluralize
        end

        def i18n_scope
          @i18n_scope ||= file_path.gsub('/', '.')
        end

        def table_name
          @table_name ||= begin
            base = pluralize_table_names? ? plural_name : singular_name
            (class_path + [base]).join('_')
          end
        end

        def uncountable?
          singular_name == plural_name
        end

        def index_helper
          uncountable? ? "#{plural_table_name}_index" : plural_table_name
        end

        def singular_table_name
          @singular_table_name ||= (pluralize_table_names? ? table_name.singularize : table_name)
        end

        def plural_table_name
          @plural_table_name ||= (pluralize_table_names? ? table_name : table_name.pluralize)
        end

        def plural_file_name
          @plural_file_name ||= file_name.pluralize
        end

        def route_url
          @route_url ||= class_path.collect{|dname| "/" + dname }.join('') + "/" + plural_file_name
        end

        # Tries to retrieve the application name or simple return application.
        def application_name
          if defined?(Rails) && Rails.application
            Rails.application.class.name.split('::').first.underscore
          else
            "application"
          end
        end

        def assign_names!(name) #:nodoc:
          @class_path = name.include?('/') ? name.split('/') : name.split('::')
          @class_path.map! { |m| m.underscore }
          @file_name = @class_path.pop
        end

        # Convert attributes array into GeneratedAttribute objects.
        def parse_attributes! #:nodoc:
          self.attributes = (attributes || []).map do |attr|
            Rails::Generators::GeneratedAttribute.parse(attr)
          end
        end

        def pluralize_table_names?
          !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
        end

        # Add a class collisions name to be checked on class initialization. You
        # can supply a hash with a :prefix or :suffix to be tested.
        #
        # ==== Examples
        #
        # check_class_collision :suffix => "Observer"
        #
        # If the generator is invoked with class name Admin, it will check for
        # the presence of "AdminObserver".
        #
        def self.check_class_collision(options={})
          define_method :check_class_collision do
            name = if self.respond_to?(:controller_class_name) # for ScaffoldBase
              controller_class_name
            else
              class_name
            end

            class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
          end
        end

        # Returns Ruby 1.9 style key-value pair if current code is running on
        # Ruby 1.9.x. Returns the old-style (with hash rocket) otherwise.
        def key_value(key, value)
          if options[:old_style_hash] || RUBY_VERSION < '1.9'
            ":#{key} => #{value}"
          else
            "#{key}: #{value}"
          end
        end
    end
  end
end
Something went wrong with that request. Please try again.