aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile1
-rw-r--r--actionmailer/lib/action_mailer/collector.rb2
-rw-r--r--actionpack/lib/abstract_controller/collector.rb4
-rw-r--r--actionpack/lib/action_controller/metal/rack_delegation.rb10
-rw-r--r--actionpack/lib/action_controller/metal/testing.rb31
-rw-r--r--actionpack/lib/action_controller/test_case.rb65
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb18
-rw-r--r--actionpack/lib/action_dispatch/testing/test_request.rb8
-rw-r--r--actionpack/test/controller/mime_responds_test.rb4
-rw-r--r--actionpack/test/controller/test_case_test.rb9
-rw-r--r--actionpack/test/dispatch/mime_type_test.rb14
-rw-r--r--activerecord/CHANGELOG.md20
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb2
-rw-r--r--activerecord/lib/active_record/model.rb4
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb4
-rw-r--r--activerecord/lib/active_record/relation.rb4
-rw-r--r--activerecord/test/cases/column_test.rb6
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb2
-rw-r--r--activerecord/test/cases/query_cache_test.rb8
-rw-r--r--activerecord/test/cases/quoting_test.rb8
-rw-r--r--activerecord/test/cases/relations_test.rb5
-rw-r--r--activesupport/activesupport.gemspec1
-rw-r--r--activesupport/lib/active_support/test_case.rb1
-rw-r--r--activesupport/lib/active_support/testing/setup_and_teardown.rb9
-rw-r--r--guides/code/getting_started/test/test_helper.rb2
-rw-r--r--guides/source/4_0_release_notes.textile29
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/test_helper.rb2
-rw-r--r--railties/lib/rails/generators/rails/model/USAGE49
-rw-r--r--railties/lib/rails/test_help.rb5
30 files changed, 255 insertions, 82 deletions
diff --git a/Gemfile b/Gemfile
index 6bb6b03671..1c378c7a68 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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