diff options
30 files changed, 255 insertions, 82 deletions
| @@ -8,7 +8,6 @@ else    gem 'arel'  end -gem 'minitest', '~> 3.2.0'  gem 'mocha', '>= 0.11.2', :require => false  gem 'rack-test', github: "brynary/rack-test"  gem 'bcrypt-ruby', '~> 3.0.0' diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb index 17b22aea2a..b8d1db9558 100644 --- a/actionmailer/lib/action_mailer/collector.rb +++ b/actionmailer/lib/action_mailer/collector.rb @@ -15,7 +15,7 @@ module ActionMailer #:nodoc:      def any(*args, &block)        options = args.extract_options! -      raise "You have to supply at least one format" if args.empty? +      raise ArgumentError, "You have to supply at least one format" if args.empty?        args.each { |type| send(type, options.dup, &block) }      end      alias :all :any diff --git a/actionpack/lib/abstract_controller/collector.rb b/actionpack/lib/abstract_controller/collector.rb index 492329c401..09b9e7ddf0 100644 --- a/actionpack/lib/abstract_controller/collector.rb +++ b/actionpack/lib/abstract_controller/collector.rb @@ -16,6 +16,10 @@ module AbstractController        generate_method_for_mime(mime)      end +    Mime::Type.register_callback do |mime| +      generate_method_for_mime(mime) unless self.instance_methods.include?(mime.to_sym) +    end +    protected      def method_missing(symbol, &block) diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index f01f4b99a9..bdf6e88699 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -9,8 +9,7 @@ module ActionController               :status, :location, :content_type, :to => "@_response"      def dispatch(action, request) -      @_response         = ActionDispatch::Response.new -      @_response.request = request +      set_response!(request)        super(action, request)      end @@ -22,5 +21,12 @@ module ActionController      def reset_session        @_request.reset_session      end + +    private + +    def set_response!(request) +      @_response         = ActionDispatch::Response.new +      @_response.request = request +    end    end  end diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb index d1813ee745..0377b8c4cf 100644 --- a/actionpack/lib/action_controller/metal/testing.rb +++ b/actionpack/lib/action_controller/metal/testing.rb @@ -4,30 +4,25 @@ module ActionController      include RackDelegation -    def recycle! -      @_url_options = nil -    end - - -    # TODO: Clean this up -    def process_with_new_base_test(request, response) -      @_request = request -      @_response = response -      @_response.request = request -      ret = process(request.parameters[:action]) -      if cookies = @_request.env['action_dispatch.cookies'] -        cookies.write(@_response) -      end -      @_response.prepare! -      ret -    end -      # TODO : Rewrite tests using controller.headers= to use Rack env      def headers=(new_headers)        @_response ||= ActionDispatch::Response.new        @_response.headers.replace(new_headers)      end +    # Behavior specific to functional tests +    module Functional # :nodoc: +      def set_response!(request) +      end + +      def recycle! +        @_url_options = nil +        self.response_body = nil +        self.formats = nil +        self.params = nil +      end +    end +      module ClassMethods        def before_filters          _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name} diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index a1f29ea1bc..0498b9d138 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -143,6 +143,9 @@ module ActionController    end    class TestRequest < ActionDispatch::TestRequest #:nodoc: +    DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup +    DEFAULT_ENV.delete 'PATH_INFO' +      def initialize(env = {})        super @@ -150,10 +153,6 @@ module ActionController        self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => SecureRandom.hex(16))      end -    class Result < ::Array #:nodoc: -      def to_s() join '/' end -    end -      def assign_parameters(routes, controller_path, action, parameters = {})        parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)        extra_keys = routes.extra_keys(parameters) @@ -171,7 +170,7 @@ module ActionController            non_path_parameters[key] = value          else            if value.is_a?(Array) -            value = Result.new(value.map(&:to_param)) +            value = value.map(&:to_param)            else              value = value.to_param            end @@ -211,6 +210,12 @@ module ActionController        cookie_jar.update(@set_cookies)        cookie_jar.recycle!      end + +    private + +    def default_env +      DEFAULT_ENV +    end    end    class TestResponse < ActionDispatch::TestResponse @@ -430,8 +435,13 @@ module ActionController        end        # Executes a request simulating HEAD HTTP method and set/volley the response -      def head(action, parameters = nil, session = nil, flash = nil) -        process(action, "HEAD", parameters, session, flash) +      def head(action, *args) +        process(action, "HEAD", *args) +      end + +      # Executes a request simulating OPTIONS HTTP method and set/volley the response +      def options(action, *args) +        process(action, "OPTIONS", *args)        end        def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil) @@ -471,13 +481,17 @@ module ActionController          # proper params, as is the case when engaging rack.          parameters = paramify_values(parameters) if html_format?(parameters) +        @html_document = nil + +        unless @controller.respond_to?(:recycle!) +          @controller.extend(Testing::Functional) +          @controller.class.class_eval { include Testing } +        end +          @request.recycle!          @response.recycle! -        @controller.response_body = nil -        @controller.formats = nil -        @controller.params = nil +        @controller.recycle! -        @html_document = nil          @request.env['REQUEST_METHOD'] = http_method          parameters ||= {} @@ -490,26 +504,34 @@ module ActionController          @request.session.update(session) if session          @request.session["flash"] = @request.flash.update(flash || {}) -        @controller.request = @request +        @controller.request  = @request +        @controller.response = @response +          build_request_uri(action, parameters) -        @controller.class.class_eval { include Testing } -        @controller.recycle! -        @controller.process_with_new_base_test(@request, @response) + +        name = @request.parameters[:action] + +        @controller.process(name) + +        if cookies = @request.env['action_dispatch.cookies'] +          cookies.write(@response) +        end +        @response.prepare! +          @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}          @request.session.delete('flash') if @request.session['flash'].blank?          @response        end        def setup_controller_request_and_response -        @request = TestRequest.new -        @response = TestResponse.new +        @request          = TestRequest.new +        @response         = TestResponse.new +        @response.request = @request          if klass = self.class.controller_class            @controller ||= klass.new rescue nil          end -        @request.env.delete('PATH_INFO') -          if defined?(@controller) && @controller            @controller.request = @request            @controller.params = {} @@ -523,7 +545,7 @@ module ActionController          setup :setup_controller_request_and_response        end -    private +      private        def check_required_ivars          # Sanity check for required instance variables so we can give an          # understandable error message. @@ -564,8 +586,7 @@ module ActionController        def html_format?(parameters)          return true unless parameters.is_a?(Hash) -        format = Mime[parameters[:format]] -        format.nil? || format.html? +        Mime.fetch(parameters[:format]) { Mime['html'] }.html?        end      end diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index ee1913dbf9..fe39c220a5 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -29,6 +29,11 @@ module Mime      Type.lookup_by_extension(type.to_s)    end +  def self.fetch(type) +    return type if type.is_a?(Type) +    EXTENSION_LOOKUP.fetch(type.to_s) { |k| yield k } +  end +    # Encapsulates the notion of a mime type. Can be used at render time, for example, with:    #    #   class PostsController < ActionController::Base @@ -53,6 +58,8 @@ module Mime      cattr_reader :browser_generated_types      attr_reader :symbol +    @register_callbacks = [] +      # A simple helper class used in parsing the accept header      class AcceptItem #:nodoc:        attr_accessor :order, :name, :q @@ -84,6 +91,10 @@ module Mime        TRAILING_STAR_REGEXP = /(text|application)\/\*/        PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/ +      def register_callback(&block) +        @register_callbacks << block +      end +        def lookup(string)          LOOKUP[string]        end @@ -101,10 +112,15 @@ module Mime        def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)          Mime.const_set(symbol.upcase, Type.new(string, symbol, mime_type_synonyms)) -        SET << Mime.const_get(symbol.upcase) +        new_mime = Mime.const_get(symbol.upcase) +        SET << new_mime          ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = SET.last } unless skip_lookup          ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = SET.last } + +        @register_callbacks.each do |callback| +          callback.call(new_mime) +        end        end        def parse(accept_header) diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb index a86b510719..639ae6f398 100644 --- a/actionpack/lib/action_dispatch/testing/test_request.rb +++ b/actionpack/lib/action_dispatch/testing/test_request.rb @@ -12,7 +12,7 @@ module ActionDispatch      def initialize(env = {})        env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application -      super(DEFAULT_ENV.merge(env)) +      super(default_env.merge(env))        self.host        = 'test.host'        self.remote_addr = '0.0.0.0' @@ -69,5 +69,11 @@ module ActionDispatch      def cookies        @cookies ||= {}.with_indifferent_access      end + +    private + +    def default_env +      DEFAULT_ENV +    end    end  end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index bdcd5561a8..c8e036b116 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -505,7 +505,7 @@ class RespondToControllerTest < ActionController::TestCase  end  class RespondWithController < ActionController::Base -  respond_to :html, :json +  respond_to :html, :json, :touch    respond_to :xml, :except => :using_resource_with_block    respond_to :js,  :only => [ :using_resource_with_block, :using_resource, 'using_hash_resource' ] @@ -623,12 +623,14 @@ class RespondWithControllerTest < ActionController::TestCase      super      @request.host = "www.example.com"      Mime::Type.register_alias('text/html', :iphone) +    Mime::Type.register_alias('text/html', :touch)      Mime::Type.register('text/x-mobile', :mobile)    end    def teardown      super      Mime::Type.unregister(:iphone) +    Mime::Type.unregister(:touch)      Mime::Type.unregister(:mobile)    end diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index 49137946fe..8990fc34d6 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -197,6 +197,11 @@ XML      assert_raise(NoMethodError) { head :test_params, "document body", :id => 10 }    end +  def test_options +    options :test_params +    assert_equal 200, @response.status +  end +    def test_process_without_flash      process :set_flash      assert_equal '><', flash['test'] @@ -635,7 +640,7 @@ XML        get :test_params, :path => ['hello', 'world']        assert_equal ['hello', 'world'], @request.path_parameters['path'] -      assert_equal 'hello/world', @request.path_parameters['path'].to_s +      assert_equal 'hello/world', @request.path_parameters['path'].to_param      end    end @@ -913,4 +918,4 @@ class AnonymousControllerTest < ActionController::TestCase      get :index      assert_equal 'anonymous', @response.body    end -end
\ No newline at end of file +end diff --git a/actionpack/test/dispatch/mime_type_test.rb b/actionpack/test/dispatch/mime_type_test.rb index 9d77c3acc5..ed012093a7 100644 --- a/actionpack/test/dispatch/mime_type_test.rb +++ b/actionpack/test/dispatch/mime_type_test.rb @@ -118,6 +118,20 @@ class MimeTypeTest < ActiveSupport::TestCase      end    end +  test "register callbacks" do +    begin +      registered_mimes = [] +      Mime::Type.register_callback do |mime| +        registered_mimes << mime +      end + +      Mime::Type.register("text/foo", :foo) +      assert_equal registered_mimes, [Mime::FOO] +    ensure +      Mime::Type.unregister(:FOO) +    end +  end +    test "custom type with extension aliases" do      begin        Mime::Type.register "text/foobar", :foobar, [], [:foo, "bar"] diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 32261ba9e6..ccaa2ad8f1 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -2,11 +2,11 @@  *   Add `add_reference` and `remove_reference` schema statements. Aliases, `add_belongs_to`      and `remove_belongs_to` are acceptable. References are reversible. -		Examples: +    Examples:          # Create a user_id column          add_reference(:products, :user) -				# Create a supplier_id, supplier_type columns and appropriate index +        # Create a supplier_id, supplier_type columns and appropriate index          add_reference(:products, :supplier, polymorphic: true, index: true)          # Remove polymorphic reference          remove_reference(:products, :supplier, polymorphic: true) @@ -20,14 +20,16 @@      *Aleksey Magusev* -*   `ActiveRelation#inspect` no longer calls `#to_a`. This means that in places -    where `#inspect` is implied (such as in the console), creating a relation -    will not execute it anymore, you'll have to call `#to_a` when necessary: +*   `ActiveRecord::Relation#inspect` now makes it clear that you are +    dealing with a `Relation` object rather than an array:. -       User.where(:age => 30)      # => returns the relation -       User.where(:age => 30).to_a # => executes the query and returns the loaded objects, as before +       User.where(:age => 30).inspect +       # => <ActiveRecord::Relation [#<User ...>, #<User ...>]> -    *Brian Cardarella* +       User.where(:age => 30).to_a.inspect +       # => [#<User ...>, #<User ...>] + +    *Brian Cardarella & Jon Leighton*  *   Add `collation` and `ctype` support to PostgreSQL. These are available for PostgreSQL 8.4 or later.      Example: @@ -865,7 +867,7 @@  *   LRU cache in mysql and sqlite are now per-process caches. -    * lib/active_record/connection_adapters/mysql_adapter.rb: LRU cache  	  keys are per process id. +    * lib/active_record/connection_adapters/mysql_adapter.rb: LRU cache     keys are per process id.      * lib/active_record/connection_adapters/sqlite_adapter.rb: ditto      *Aaron Patterson* diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 3b4537aab4..a6e16da730 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -56,7 +56,7 @@ module ActiveRecord        end        def select_all(arel, name = nil, binds = []) -        if @query_cache_enabled +        if @query_cache_enabled && !locked?(arel)            sql = to_sql(arel, binds)            cache_sql(sql, binds) { super(sql, name, binds) }          else @@ -83,6 +83,14 @@ module ActiveRecord            result.collect { |row| row.dup }          end        end + +      def locked?(arel) +        if arel.respond_to?(:locked) +          arel.locked +        else +          false +        end +      end      end    end  end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb index 6f9f0399db..60a9eee7c7 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb @@ -31,7 +31,7 @@ module ActiveRecord            # BigDecimals need to be put in a non-normalized form and quoted.          when nil        then "NULL"          when BigDecimal then value.to_s('F') -        when Numeric    then value.to_s +        when Numeric, ActiveSupport::Duration then value.to_s          when Date, Time then "'#{quoted_date(value)}'"          when Symbol     then "'#{quote_string(value.to_s)}'"          when Class      then "'#{value.to_s}'" diff --git a/activerecord/lib/active_record/model.rb b/activerecord/lib/active_record/model.rb index 7b3d926d91..0015e3a567 100644 --- a/activerecord/lib/active_record/model.rb +++ b/activerecord/lib/active_record/model.rb @@ -103,7 +103,9 @@ module ActiveRecord        def abstract_class?          false        end - +       +      # Defines the name of the table column which will store the class name on single-table +      # inheritance situations.        def inheritance_column          'type'        end diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index 841681e542..7febb5539f 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -351,7 +351,7 @@ module ActiveRecord          if respond_to?(method)            send(method, attributes.except(*unassignable_keys(assignment_opts)), assignment_opts)          else -          raise ArgumentError, "Cannot build association #{association_name}. Are you trying to build a polymorphic one-to-one association?" +          raise ArgumentError, "Cannot build association `#{association_name}'. Are you trying to build a polymorphic one-to-one association?"          end        end      end @@ -373,7 +373,7 @@ module ActiveRecord      #   })      #      # Will update the name of the Person with ID 1, build a new associated -    # person with the name `John', and mark the associated Person with ID 2 +    # person with the name 'John', and mark the associated Person with ID 2      # for destruction.      #      # Also accepts an Array of attribute hashes: diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index e268d451e0..7725331694 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -514,6 +514,10 @@ module ActiveRecord        @values.dup      end +    def inspect +      "#<#{self.class.name} #{to_a.inspect}>" +    end +      private      def references_eager_loaded_tables? diff --git a/activerecord/test/cases/column_test.rb b/activerecord/test/cases/column_test.rb index 4111a5f808..a7b63d15c9 100644 --- a/activerecord/test/cases/column_test.rb +++ b/activerecord/test/cases/column_test.rb @@ -76,6 +76,12 @@ module ActiveRecord          date_string = Time.now.utc.strftime("%F")          assert_equal date_string, column.type_cast(date_string).strftime("%F")        end + +      def test_type_cast_duration_to_integer +        column = Column.new("field", nil, "integer") +        assert_equal 1800, column.type_cast(30.minutes) +        assert_equal 7200, column.type_cast(2.hours) +      end      end    end  end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 3daa033ed0..3a234f0cc1 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -196,7 +196,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase    end    def test_should_raise_argument_error_if_trying_to_build_polymorphic_belongs_to -    assert_raise_with_message ArgumentError, "Cannot build association looter. Are you trying to build a polymorphic one-to-one association?" do +    assert_raise_with_message ArgumentError, "Cannot build association `looter'. Are you trying to build a polymorphic one-to-one association?" do        Treasure.new(:name => 'pearl', :looter_attributes => {:catchphrase => "Arrr"})      end    end diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index 08f655d7fa..0153e74604 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -164,6 +164,14 @@ class QueryCacheTest < ActiveRecord::TestCase        end      end    end + +  def test_cache_is_ignored_for_locked_relations +    task = Task.find 1 + +    Task.cache do +      assert_queries(2) { task.lock!; task.lock! } +    end +  end  end  class QueryCacheExpiryTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/quoting_test.rb b/activerecord/test/cases/quoting_test.rb index 80ee74e41e..3dd11ae89d 100644 --- a/activerecord/test/cases/quoting_test.rb +++ b/activerecord/test/cases/quoting_test.rb @@ -216,6 +216,14 @@ module ActiveRecord        def test_string_with_crazy_column          assert_equal "'lo\\\\l'", @quoter.quote('lo\l', FakeColumn.new(:foo))        end + +      def test_quote_duration +        assert_equal "1800", @quoter.quote(30.minutes) +      end + +      def test_quote_duration_int_column +        assert_equal "7200", @quoter.quote(2.hours, FakeColumn.new(:integer)) +      end      end    end  end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 8544d36aa8..7fdd42f150 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -1311,4 +1311,9 @@ class RelationTest < ActiveRecord::TestCase        relation.merge! where: 'foo'      end    end + +  test "relations show the records in #inspect" do +    relation = Post.limit(2) +    assert_equal "#<ActiveRecord::Relation [#{Post.limit(2).map(&:inspect).join(', ')}]>", relation.inspect +  end  end diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec index fa38d5c1e3..836bc2f9cf 100644 --- a/activesupport/activesupport.gemspec +++ b/activesupport/activesupport.gemspec @@ -22,4 +22,5 @@ Gem::Specification.new do |s|    s.add_dependency('i18n',       '~> 0.6')    s.add_dependency('multi_json', '~> 1.3')    s.add_dependency('tzinfo',     '~> 0.3.33') +  s.add_dependency('minitest',   '~> 3.2')  end diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb index b6abc3b561..a6f3b43792 100644 --- a/activesupport/lib/active_support/test_case.rb +++ b/activesupport/lib/active_support/test_case.rb @@ -1,3 +1,4 @@ +gem 'minitest' # make sure we get the gem, not stdlib  require 'minitest/spec'  require 'active_support/testing/setup_and_teardown'  require 'active_support/testing/assertions' diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb index ddb7396aa9..a65148cf1f 100644 --- a/activesupport/lib/active_support/testing/setup_and_teardown.rb +++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb @@ -4,20 +4,11 @@ require 'active_support/callbacks'  module ActiveSupport    module Testing      module SetupAndTeardown - -      PASSTHROUGH_EXCEPTIONS = [ -        NoMemoryError, -        SignalException, -        Interrupt, -        SystemExit -      ] -        extend ActiveSupport::Concern        included do          include ActiveSupport::Callbacks          define_callbacks :setup, :teardown -        end        module ClassMethods diff --git a/guides/code/getting_started/test/test_helper.rb b/guides/code/getting_started/test/test_helper.rb index 8bf1192ffe..3daca18a71 100644 --- a/guides/code/getting_started/test/test_helper.rb +++ b/guides/code/getting_started/test/test_helper.rb @@ -3,7 +3,7 @@ require File.expand_path('../../config/environment', __FILE__)  require 'rails/test_help'  class ActiveSupport::TestCase -  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. +  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.    #    # Note: You'll currently still have to declare fixtures explicitly in integration tests    # -- they do not yet inherit this setting diff --git a/guides/source/4_0_release_notes.textile b/guides/source/4_0_release_notes.textile index e1d6b42e6c..8415f6f83a 100644 --- a/guides/source/4_0_release_notes.textile +++ b/guides/source/4_0_release_notes.textile @@ -329,6 +329,20 @@ Moved into a separate gem <tt>sprockets-rails</tt>.  h3. Active Record +* Add <tt>add_reference</tt> and <tt>remove_reference</tt> schema statements. Aliases, <tt>add_belongs_to</tt> and <tt>remove_belongs_to</tt> are acceptable. References are reversible. + +<ruby> +# Create a user_id column +add_reference(:products, :user) + +# Create a supplier_id, supplier_type columns and appropriate index +add_reference(:products, :supplier, polymorphic: true, index: true) + +# Remove polymorphic reference +remove_reference(:products, :supplier, polymorphic: true) +</ruby> + +  * Add <tt>:default</tt> and <tt>:null</tt> options to <tt>column_exists?</tt>.  <ruby> @@ -336,14 +350,17 @@ column_exists?(:testings, :taggable_id, :integer, null: false)  column_exists?(:testings, :taggable_type, :string, default: 'Photo')  </ruby> -* <tt>ActiveRelation#inspect</tt> no longer calls <tt>#to_a</tt>. This means that in places where <tt>#inspect</tt> is implied (such as in the console), creating a relation will not execute it anymore, you'll have to call <tt>#to_a</tt> when necessary: +* <tt>ActiveRecord::Relation#inspect</tt> now makes it clear that you are dealing with a <tt>Relation</tt> object rather than an array:  <ruby> -User.where(:age => 30)      # => returns the relation -User.where(:age => 30).to_a # => executes the query and returns the loaded objects, as before +User.where(:age => 30).inspect +# => <ActiveRecord::Relation [#<User ...>, #<User ...>]> + +User.where(:age => 30).to_a.inspect +# => [#<User ...>, #<User ...>]  </ruby> -* Add <tt>collation</tt> and <tt>ctype</tt> support to PostgreSQL. These are available for PostgreSQL 8.4 or later. +* Add <tt>:collation</tt> and <tt>:ctype</tt> support to PostgreSQL. These are available for PostgreSQL 8.4 or later.  <yaml>  development: @@ -506,7 +523,7 @@ Post.find_by! name: 'Spartacus'  * Added <tt>ActiveRecord::Base#slice</tt> to return a hash of the given methods with their names as keys and returned values as values. -* Remove IdentityMap - IdentityMap has never graduated to be an "enabled-by-default" feature, due to some inconsistencies with associations, as described in this commit: https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6. Hence the removal from the codebase, until such issues are fixed. +* Remove IdentityMap - IdentityMap has never graduated to be an "enabled-by-default" feature, due to some inconsistencies with associations, as described in this "commit":https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6. Hence the removal from the codebase, until such issues are fixed.  * Added a feature to dump/load internal state of +SchemaCache+ instance because we want to boot more quickly when we have many models. @@ -708,7 +725,7 @@ h4(#activemodel_deprecations). Deprecations  h3. Active Resource -* Active Resource is removed from Rails 4.0 and is now a separate gem. TODO: put a link to the gem here. +* Active Resource is removed from Rails 4.0 and is now a separate "gem":https://github.com/rails/activeresource.  h3. Active Support diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb index 0090293200..9afda2d0df 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb @@ -6,7 +6,7 @@ class ActiveSupport::TestCase  <% unless options[:skip_active_record] -%>    ActiveRecord::Migration.check_pending! -  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. +  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.    #    # Note: You'll currently still have to declare fixtures explicitly in integration tests    # -- they do not yet inherit this setting diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index 67f76aad01..c46c86076e 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -19,6 +19,55 @@ Description:      then the generator will create a module with a table_name_prefix method      to prefix the model's table name with the module name (e.g. admin_account) +Available field types: + +    Just after the field name you can specify a type like text or boolean.  +    It will generate the column with the associated SQL type. For instance: + +        `rails generate model post title:string body:text` + +    will generate a title column with a varchar type and a body column with a text  +    type. You can use the following types: + +        integer +        primary_key +        decimal +        float +        boolean +        binary +        string +        text +        date +        time +        datetime +        timestamp + +    You can also consider `references` as a kind of type. For instance, if you run: + +        `rails generate model photo title:string album:references` + +    It will generate an album_id column. You should generate this kind of fields when +    you will use a `belongs_to` association for instance. `references` also support +    the polymorphism, you could enable the polymorphism like this: + +        `rails generate model product supplier:references{polymorphic}` + +    You can also specify some options just after the field type. You can use the +    following options: + +        limit        Set the maximum size of the field giving a number between curly braces +        default      Set a default value for the field +        precision    Defines the precision for the decimal fields  +        scale        Defines the scale for the decimal fields +        uniq         Defines the field values as unique  +        index        Will add an index on the field + +    Examples: + +        `rails generate model user pseudo:string{30}` +        `rails generate model user pseudo:string:uniq` +         +  Examples:      `rails generate model account` diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index 46bf3bbe48..581ceaf9ce 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -10,7 +10,10 @@ require 'action_dispatch/testing/integration'  # Enable turn if it is available  begin    require 'turn' -  MiniTest::Unit.use_natural_language_case_names = true + +  Turn.config do |c| +    c.natural = true +  end  rescue LoadError  end | 
