aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG.md12
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb20
-rw-r--r--actionpack/lib/action_dispatch/journey/visualizer/index.html.erb4
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb49
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb10
-rw-r--r--actionpack/test/dispatch/url_generation_test.rb18
-rw-r--r--actionpack/test/journey/router_test.rb6
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb4
-rw-r--r--actionview/lib/action_view/rendering.rb4
-rw-r--r--activerecord/CHANGELOG.md19
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb134
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb178
-rw-r--r--activerecord/lib/active_record/connection_adapters/schema_cache.rb42
-rw-r--r--activerecord/lib/active_record/connection_adapters/type.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/decimal_without_scale.rb13
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb12
-rw-r--r--activerecord/test/cases/connection_adapters/type_lookup_test.rb16
-rw-r--r--activerecord/test/cases/relation/where_chain_test.rb2
-rw-r--r--activesupport/lib/active_support/dependencies.rb9
-rw-r--r--guides/source/configuring.md42
-rw-r--r--railties/CHANGELOG.md3
-rw-r--r--railties/lib/rails/generators/named_base.rb7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile2
25 files changed, 328 insertions, 292 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 2b4ff7f03d..86e98c011c 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,9 +1,14 @@
+* Fix URL generation with `:trailing_slash` such that it does not add
+ a trailing slash after `.:format`
+
+ *Dan Langevin*
+
* Build full URI as string when processing path in integration tests for
performance reasons.
*Guo Xiang Tan*
-* Fix 'Stack level too deep' when rendering `head :ok` in an action method
+* Fix `'Stack level too deep'` when rendering `head :ok` in an action method
called 'status' in a controller.
Fixes #13905.
@@ -71,7 +76,7 @@
4. Use `escape_segment` rather than `escape_path` in URL generation
For point 4 there are two exceptions. Firstly, when a route uses wildcard segments
- (e.g. *foo) then we use `escape_path` as the value may contain '/' characters. This
+ (e.g. `*foo`) then we use `escape_path` as the value may contain '/' characters. This
means that wildcard routes can't be optimized. Secondly, if a `:controller` segment
is used in the path then this uses `escape_path` as the controller may be namespaced.
@@ -101,7 +106,7 @@
*Andrew White*, *James Coglan*
-* Append link to bad code to backtrace when exception is SyntaxError.
+* Append link to bad code to backtrace when exception is `SyntaxError`.
*Boris Kuznetsov*
@@ -131,4 +136,5 @@
*Tony Wooster*
+
Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionpack/CHANGELOG.md) for previous changes.
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index a6c17f50a5..4cba4f5f37 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -37,13 +37,7 @@ module ActionDispatch
path = options[:script_name].to_s.chomp("/")
path << options[:path].to_s
- if options[:trailing_slash]
- if path.include?('?')
- path.sub!(/\?/, '/\&')
- else
- path.sub!(/[^\/]\z|\A\z/, '\&/')
- end
- end
+ add_trailing_slash(path) if options[:trailing_slash]
result = path
@@ -66,6 +60,18 @@ module ActionDispatch
private
+ def add_trailing_slash(path)
+ # includes querysting
+ if path.include?('?')
+ path.sub!(/\?/, '/\&')
+ # does not have a .format
+ elsif !path.include?(".")
+ path.sub!(/[^\/]\z|\A\z/, '\&/')
+ end
+
+ path
+ end
+
def build_host_url(options)
if match = options[:host].match(HOST_REGEXP)
options[:protocol] ||= match[1] unless options[:protocol] == false
diff --git a/actionpack/lib/action_dispatch/journey/visualizer/index.html.erb b/actionpack/lib/action_dispatch/journey/visualizer/index.html.erb
index 6aff10956a..9b28a65200 100644
--- a/actionpack/lib/action_dispatch/journey/visualizer/index.html.erb
+++ b/actionpack/lib/action_dispatch/journey/visualizer/index.html.erb
@@ -2,13 +2,13 @@
<html>
<head>
<title><%= title %></title>
- <link rel="stylesheet" href="https://raw.github.com/gist/1706081/af944401f75ea20515a02ddb3fb43d23ecb8c662/reset.css" type="text/css">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" type="text/css">
<style>
<% stylesheets.each do |style| %>
<%= style %>
<% end %>
</style>
- <script src="https://raw.github.com/gist/1706081/df464722a05c3c2bec450b7b5c8240d9c31fa52d/d3.min.js" type="text/javascript"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js" type="text/javascript"></script>
</head>
<body>
<div id="wrapper">
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 7e78b417fa..f39fd1ea35 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -16,14 +16,6 @@ module ActionDispatch
:shallow, :blocks, :defaults, :options]
class Constraints #:nodoc:
- def self.new(app, constraints, request = Rack::Request)
- if constraints.any?
- super(app, constraints, request)
- else
- app
- end
- end
-
attr_reader :app, :constraints
def initialize(app, constraints, request)
@@ -57,12 +49,18 @@ module ActionDispatch
WILDCARD_PATH = %r{\*([^/\)]+)\)?$}
attr_reader :scope, :path, :options, :requirements, :conditions, :defaults
+ attr_reader :to, :default_controller, :default_action
def initialize(set, scope, path, options)
- @set, @scope, @path, @options = set, scope, path, options
+ @set, @scope, @path = set, scope, path
@requirements, @conditions, @defaults = {}, {}, {}
- normalize_options!
+ options = scope[:options].merge(options) if scope[:options]
+ @to = options[:to]
+ @default_controller = options[:controller] || scope[:controller]
+ @default_action = options[:action] || scope[:action]
+
+ @options = normalize_options!(options)
normalize_path!
normalize_requirements!
normalize_conditions!
@@ -94,14 +92,13 @@ module ActionDispatch
options[:format] != false && !path.include?(':format') && !path.end_with?('/')
end
- def normalize_options!
- @options.reverse_merge!(scope[:options]) if scope[:options]
+ def normalize_options!(options)
path_without_format = path.sub(/\(\.:format\)$/, '')
# Add a constraint for wildcard route to make it non-greedy and match the
# optional format part of the route by default
- if path_without_format.match(WILDCARD_PATH) && @options[:format] != false
- @options[$1.to_sym] ||= /.+?/
+ if path_without_format.match(WILDCARD_PATH) && options[:format] != false
+ options[$1.to_sym] ||= /.+?/
end
if path_without_format.match(':controller')
@@ -111,10 +108,10 @@ module ActionDispatch
# controllers with default routes like :controller/:action/:id(.:format), e.g:
# GET /admin/products/show/1
# => { controller: 'admin/products', action: 'show', id: '1' }
- @options[:controller] ||= /.+?/
+ options[:controller] ||= /.+?/
end
- @options.merge!(default_controller_and_action)
+ options.merge!(default_controller_and_action)
end
def normalize_requirements!
@@ -210,7 +207,11 @@ module ActionDispatch
end
def app
- Constraints.new(endpoint, blocks, @set.request_class)
+ if blocks.any?
+ Constraints.new(endpoint, blocks, @set.request_class)
+ else
+ endpoint
+ end
end
def default_controller_and_action
@@ -301,19 +302,7 @@ module ActionDispatch
end
def dispatcher
- Routing::RouteSet::Dispatcher.new(:defaults => defaults)
- end
-
- def to
- options[:to]
- end
-
- def default_controller
- options[:controller] || scope[:controller]
- end
-
- def default_action
- options[:action] || scope[:action]
+ Routing::RouteSet::Dispatcher.new(defaults)
end
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index e9fb712a61..40c767e685 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -21,9 +21,8 @@ module ActionDispatch
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
class Dispatcher #:nodoc:
- def initialize(options={})
- @defaults = options[:defaults]
- @glob_param = options.delete(:glob)
+ def initialize(defaults)
+ @defaults = defaults
@controller_class_names = ThreadSafe::Cache.new
end
@@ -53,7 +52,6 @@ module ActionDispatch
def prepare_params!(params)
normalize_controller!(params)
merge_default_action!(params)
- split_glob_param!(params) if @glob_param
end
# If this is a default_controller (i.e. a controller specified by the user)
@@ -89,10 +87,6 @@ module ActionDispatch
def merge_default_action!(params)
params[:action] ||= 'index'
end
-
- def split_glob_param!(params)
- params[@glob_param] = params[@glob_param].split('/').map { |v| URI.parser.unescape(v) }
- end
end
# A NamedRouteCollection instance is a collection of named routes, and also
diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb
index 910ff8a80f..a4dfd0a63d 100644
--- a/actionpack/test/dispatch/url_generation_test.rb
+++ b/actionpack/test/dispatch/url_generation_test.rb
@@ -15,6 +15,8 @@ module TestUrlGeneration
Routes.draw do
get "/foo", :to => "my_route_generating#index", :as => :foo
+ resources :bars
+
mount MyRouteGeneratingController.action(:index), at: '/bar'
end
@@ -109,6 +111,22 @@ module TestUrlGeneration
test "omit subdomain when key is blank" do
assert_equal "http://example.com/foo", foo_url(subdomain: "")
end
+
+ test "generating URLs with trailing slashes" do
+ assert_equal "/bars.json", bars_path(
+ trailing_slash: true,
+ format: 'json'
+ )
+ end
+
+ test "generating URLS with querystring and trailing slashes" do
+ assert_equal "/bars.json?a=b", bars_path(
+ trailing_slash: true,
+ a: 'b',
+ format: 'json'
+ )
+ end
+
end
end
diff --git a/actionpack/test/journey/router_test.rb b/actionpack/test/journey/router_test.rb
index 6252458861..db2d3bc10d 100644
--- a/actionpack/test/journey/router_test.rb
+++ b/actionpack/test/journey/router_test.rb
@@ -5,7 +5,11 @@ module ActionDispatch
module Journey
class TestRouter < ActiveSupport::TestCase
# TODO : clean up routing tests so we don't need this hack
- class StubDispatcher < Routing::RouteSet::Dispatcher; end
+ class StubDispatcher < Routing::RouteSet::Dispatcher
+ def initialize
+ super({})
+ end
+ end
attr_reader :routes
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 10dcb5c28c..1e818083cc 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -109,8 +109,8 @@ module ActionView
# # => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
# # <option>Out</option></select>
#
- # select_tag "access", "<option>Read</option><option>Write</option>".html_safe, multiple: true, class: 'form_input'
- # # => <select class="form_input" id="access" multiple="multiple" name="access[]"><option>Read</option>
+ # select_tag "access", "<option>Read</option><option>Write</option>".html_safe, multiple: true, class: 'form_input', id: 'unique_id'
+ # # => <select class="form_input" id="unique_id" multiple="multiple" name="access[]"><option>Read</option>
# # <option>Write</option></select>
#
# select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: true
diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb
index 017302d40f..c92d090cce 100644
--- a/actionview/lib/action_view/rendering.rb
+++ b/actionview/lib/action_view/rendering.rb
@@ -62,8 +62,8 @@ module ActionView
#
# The view class must have the following methods:
# View.new[lookup_context, assigns, controller]
- # Create a new ActionView instance for a controller
- # View#render[options]
+ # Create a new ActionView instance for a controller and we can also pass the arguments.
+ # View#render(option)
# Returns String with the rendered template
#
# Override this method in a module to change the default behavior.
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 260bd063aa..041872034f 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -28,7 +28,8 @@
*Brock Trappitt*
-* Fixed the inferred table name of a HABTM auxiliar table inside a schema.
+* Fixed the inferred table name of a has_and_belongs_to_many auxiliar
+ table inside a schema.
Fixes #14824
@@ -71,7 +72,7 @@
*Aaron Nelson*
-* Fix how to calculate associated class name when using namespaced `has_and_belongs_to_many`
+* Fix how to calculate associated class name when using namespaced has_and_belongs_to_many
association.
Fixes #14709.
@@ -124,7 +125,7 @@
*Innokenty Mikhailov*
-* Allow the PostgreSQL adapter to handle bigserial pk types again.
+* Allow the PostgreSQL adapter to handle bigserial primary key types again.
Fixes #10410.
@@ -139,10 +140,10 @@
*Yves Senn*
-* Fixed HABTM's CollectionAssociation size calculation.
+* Fixed has_and_belongs_to_many's CollectionAssociation size calculation.
- HABTM should fall back to using the normal CollectionAssociation's size
- calculation if the collection is not cached or loaded.
+ has_and_belongs_to_many should fall back to using the normal CollectionAssociation's
+ size calculation if the collection is not cached or loaded.
Fixes #14913, #14914.
@@ -186,10 +187,10 @@
*Eric Chahin*, *Aaron Nelson*, *Kevin Casey*
-* Stringify all variable keys of mysql connection configuration.
+* Stringify all variables keys of MySQL connection configuration.
- When the `sql_mode` variable for mysql adapters is set in the configuration
- as a `String`, it was ignored and overwritten by the strict mode option.
+ When `sql_mode` variable for MySQL adapters set in configuration as `String`
+ was ignored and overwritten by strict mode option.
Fixes #14895.
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index cdf0cbe218..ac14740cfe 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -20,15 +20,8 @@ module ActiveRecord
def prepare_column_options(column, types)
spec = {}
spec[:name] = column.name.inspect
-
- # AR has an optimization which handles zero-scale decimals as integers. This
- # code ensures that the dumper still dumps the column as a decimal.
- spec[:type] = if column.type == :integer && /^(numeric|decimal)/ =~ column.sql_type
- 'decimal'
- else
- column.type.to_s
- end
- spec[:limit] = column.limit.inspect if column.limit != types[column.type][:limit] && spec[:type] != 'decimal'
+ spec[:type] = column.type.to_s
+ spec[:limit] = column.limit.inspect if column.limit != types[column.type][:limit]
spec[:precision] = column.precision.inspect if column.precision
spec[:scale] = column.scale.inspect if column.scale
spec[:null] = 'false' unless column.null
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index ea7703c82c..ca5db4095e 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -396,7 +396,7 @@ module ActiveRecord
precision = extract_precision(sql_type)
if scale == 0
- Type::Integer.new(precision: precision)
+ Type::DecimalWithoutScale.new(precision: precision)
else
Type::Decimal.new(precision: precision, scale: scale)
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
new file mode 100644
index 0000000000..bcfd605165
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
@@ -0,0 +1,134 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module PostgreSQL
+ module ColumnMethods
+ def xml(*args)
+ options = args.extract_options!
+ column(args[0], 'xml', options)
+ end
+
+ def tsvector(*args)
+ options = args.extract_options!
+ column(args[0], 'tsvector', options)
+ end
+
+ def int4range(name, options = {})
+ column(name, 'int4range', options)
+ end
+
+ def int8range(name, options = {})
+ column(name, 'int8range', options)
+ end
+
+ def tsrange(name, options = {})
+ column(name, 'tsrange', options)
+ end
+
+ def tstzrange(name, options = {})
+ column(name, 'tstzrange', options)
+ end
+
+ def numrange(name, options = {})
+ column(name, 'numrange', options)
+ end
+
+ def daterange(name, options = {})
+ column(name, 'daterange', options)
+ end
+
+ def hstore(name, options = {})
+ column(name, 'hstore', options)
+ end
+
+ def ltree(name, options = {})
+ column(name, 'ltree', options)
+ end
+
+ def inet(name, options = {})
+ column(name, 'inet', options)
+ end
+
+ def cidr(name, options = {})
+ column(name, 'cidr', options)
+ end
+
+ def macaddr(name, options = {})
+ column(name, 'macaddr', options)
+ end
+
+ def uuid(name, options = {})
+ column(name, 'uuid', options)
+ end
+
+ def json(name, options = {})
+ column(name, 'json', options)
+ end
+
+ def citext(name, options = {})
+ column(name, 'citext', options)
+ end
+ end
+
+ class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
+ attr_accessor :array
+ end
+
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
+ include ColumnMethods
+
+ # Defines the primary key field.
+ # Use of the native PostgreSQL UUID type is supported, and can be used
+ # by defining your tables as such:
+ #
+ # create_table :stuffs, id: :uuid do |t|
+ # t.string :content
+ # t.timestamps
+ # end
+ #
+ # By default, this will use the +uuid_generate_v4()+ function from the
+ # +uuid-ossp+ extension, which MUST be enabled on your database. To enable
+ # the +uuid-ossp+ extension, you can use the +enable_extension+ method in your
+ # migrations. To use a UUID primary key without +uuid-ossp+ enabled, you can
+ # set the +:default+ option to +nil+:
+ #
+ # create_table :stuffs, id: false do |t|
+ # t.primary_key :id, :uuid, default: nil
+ # t.uuid :foo_id
+ # t.timestamps
+ # end
+ #
+ # You may also pass a different UUID generation function from +uuid-ossp+
+ # or another library.
+ #
+ # Note that setting the UUID primary key default value to +nil+ will
+ # require you to assure that you always provide a UUID value before saving
+ # a record (as primary keys cannot be +nil+). This might be done via the
+ # +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
+ def primary_key(name, type = :primary_key, options = {})
+ return super unless type == :uuid
+ options[:default] = options.fetch(:default, 'uuid_generate_v4()')
+ options[:primary_key] = true
+ column name, type, options
+ end
+
+ def column(name, type = nil, options = {})
+ super
+ column = self[name]
+ column.array = options[:array]
+
+ self
+ end
+
+ private
+
+ def create_column_definition(name, type)
+ PostgreSQL::ColumnDefinition.new name, type
+ end
+ end
+
+ class Table < ActiveRecord::ConnectionAdapters::Table
+ include ColumnMethods
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index da2144bee7..4620206e1a 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -6,6 +6,7 @@ require 'active_record/connection_adapters/postgresql/column'
require 'active_record/connection_adapters/postgresql/oid'
require 'active_record/connection_adapters/postgresql/quoting'
require 'active_record/connection_adapters/postgresql/referential_integrity'
+require 'active_record/connection_adapters/postgresql/schema_definitions'
require 'active_record/connection_adapters/postgresql/schema_statements'
require 'active_record/connection_adapters/postgresql/database_statements'
@@ -73,139 +74,6 @@ module ActiveRecord
# In addition, default connection parameters of libpq can be set per environment variables.
# See http://www.postgresql.org/docs/9.1/static/libpq-envars.html .
class PostgreSQLAdapter < AbstractAdapter
- class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
- attr_accessor :array
- end
-
- module ColumnMethods
- def xml(*args)
- options = args.extract_options!
- column(args[0], 'xml', options)
- end
-
- def tsvector(*args)
- options = args.extract_options!
- column(args[0], 'tsvector', options)
- end
-
- def int4range(name, options = {})
- column(name, 'int4range', options)
- end
-
- def int8range(name, options = {})
- column(name, 'int8range', options)
- end
-
- def tsrange(name, options = {})
- column(name, 'tsrange', options)
- end
-
- def tstzrange(name, options = {})
- column(name, 'tstzrange', options)
- end
-
- def numrange(name, options = {})
- column(name, 'numrange', options)
- end
-
- def daterange(name, options = {})
- column(name, 'daterange', options)
- end
-
- def hstore(name, options = {})
- column(name, 'hstore', options)
- end
-
- def ltree(name, options = {})
- column(name, 'ltree', options)
- end
-
- def inet(name, options = {})
- column(name, 'inet', options)
- end
-
- def cidr(name, options = {})
- column(name, 'cidr', options)
- end
-
- def macaddr(name, options = {})
- column(name, 'macaddr', options)
- end
-
- def uuid(name, options = {})
- column(name, 'uuid', options)
- end
-
- def json(name, options = {})
- column(name, 'json', options)
- end
-
- def citext(name, options = {})
- column(name, 'citext', options)
- end
- end
-
- class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
- include ColumnMethods
-
- # Defines the primary key field.
- # Use of the native PostgreSQL UUID type is supported, and can be used
- # by defining your tables as such:
- #
- # create_table :stuffs, id: :uuid do |t|
- # t.string :content
- # t.timestamps
- # end
- #
- # By default, this will use the +uuid_generate_v4()+ function from the
- # +uuid-ossp+ extension, which MUST be enabled on your database. To enable
- # the +uuid-ossp+ extension, you can use the +enable_extension+ method in your
- # migrations. To use a UUID primary key without +uuid-ossp+ enabled, you can
- # set the +:default+ option to +nil+:
- #
- # create_table :stuffs, id: false do |t|
- # t.primary_key :id, :uuid, default: nil
- # t.uuid :foo_id
- # t.timestamps
- # end
- #
- # You may also pass a different UUID generation function from +uuid-ossp+
- # or another library.
- #
- # Note that setting the UUID primary key default value to +nil+ will
- # require you to assure that you always provide a UUID value before saving
- # a record (as primary keys cannot be +nil+). This might be done via the
- # +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
- def primary_key(name, type = :primary_key, options = {})
- return super unless type == :uuid
- options[:default] = options.fetch(:default, 'uuid_generate_v4()')
- options[:primary_key] = true
- column name, type, options
- end
-
- def citext(name, options = {})
- column(name, 'citext', options)
- end
-
- def column(name, type = nil, options = {})
- super
- column = self[name]
- column.array = options[:array]
-
- self
- end
-
- private
-
- def create_column_definition(name, type)
- ColumnDefinition.new name, type
- end
- end
-
- class Table < ActiveRecord::ConnectionAdapters::Table
- include ColumnMethods
- end
-
ADAPTER_NAME = 'PostgreSQL'
NATIVE_DATABASE_TYPES = {
@@ -509,7 +377,7 @@ module ActiveRecord
end
def update_table_definition(table_name, base) #:nodoc:
- Table.new(table_name, base)
+ PostgreSQL::Table.new(table_name, base)
end
protected
@@ -543,7 +411,7 @@ module ActiveRecord
load_additional_types(type_map, [oid])
end
- type_map.fetch(normalize_oid_type(oid, fmod), sql_type) {
+ type_map.fetch(oid, fmod, sql_type) {
warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
Type::Value.new.tap do |cast_type|
type_map.register_type(oid, cast_type)
@@ -551,23 +419,6 @@ module ActiveRecord
}
end
- OID_FOR_DECIMAL_TREATED_AS_INT = 23 # :nodoc:
-
- def normalize_oid_type(ftype, fmod)
- # The type for the numeric depends on the width of the field,
- # so we'll do something special here.
- #
- # When dealing with decimal columns:
- #
- # places after decimal = fmod - 4 & 0xffff
- # places before decimal = (fmod - 4) >> 16 & 0xffff
- if ftype == 1700 && (fmod - 4 & 0xffff).zero?
- OID_FOR_DECIMAL_TREATED_AS_INT
- else
- ftype
- end
- end
-
def initialize_type_map(m)
register_class_with_limit m, 'int2', OID::Integer
m.alias_type 'int4', 'int2'
@@ -610,20 +461,27 @@ module ActiveRecord
m.alias_type 'lseg', 'varchar'
m.alias_type 'box', 'varchar'
- m.register_type 'timestamp' do |_, sql_type|
+ m.register_type 'timestamp' do |_, _, sql_type|
precision = extract_precision(sql_type)
OID::DateTime.new(precision: precision)
end
- m.register_type 'numeric' do |_, sql_type|
+ m.register_type 'numeric' do |_, fmod, sql_type|
precision = extract_precision(sql_type)
scale = extract_scale(sql_type)
- OID::Decimal.new(precision: precision, scale: scale)
- end
- m.register_type OID_FOR_DECIMAL_TREATED_AS_INT do |_, sql_type|
- precision = extract_precision(sql_type)
- OID::Integer.new(precision: precision)
+ # The type for the numeric depends on the width of the field,
+ # so we'll do something special here.
+ #
+ # When dealing with decimal columns:
+ #
+ # places after decimal = fmod - 4 & 0xffff
+ # places before decimal = (fmod - 4) >> 16 & 0xffff
+ if fmod && (fmod - 4 & 0xffff).zero?
+ Type::DecimalWithoutScale.new(precision: precision)
+ else
+ OID::Decimal.new(precision: precision, scale: scale)
+ end
end
load_additional_types(m)
@@ -918,7 +776,7 @@ module ActiveRecord
end
def create_table_definition(name, temporary, options, as = nil) # :nodoc:
- TableDefinition.new native_database_types, name, temporary, options, as
+ PostgreSQL::TableDefinition.new native_database_types, name, temporary, options, as
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
index e5c9f6f54a..4d8afcf16a 100644
--- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb
@@ -12,11 +12,10 @@ module ActiveRecord
@columns_hash = {}
@primary_keys = {}
@tables = {}
- prepare_default_proc
end
def primary_keys(table_name)
- @primary_keys[table_name]
+ @primary_keys[table_name] ||= table_exists?(table_name) ? connection.primary_key(table_name) : nil
end
# A cached lookup for table existence.
@@ -29,9 +28,9 @@ module ActiveRecord
# Add internal cache for table with +table_name+.
def add(table_name)
if table_exists?(table_name)
- @primary_keys[table_name]
- @columns[table_name]
- @columns_hash[table_name]
+ primary_keys(table_name)
+ columns(table_name)
+ columns_hash(table_name)
end
end
@@ -40,14 +39,16 @@ module ActiveRecord
end
# Get the columns for a table
- def columns(table)
- @columns[table]
+ def columns(table_name)
+ @columns[table_name] ||= connection.columns(table_name)
end
# Get the columns for a table as a hash, key is the column name
# value is the column object.
- def columns_hash(table)
- @columns_hash[table]
+ def columns_hash(table_name)
+ @columns_hash[table_name] ||= Hash[columns(table_name).map { |col|
+ [col.name, col]
+ }]
end
# Clears out internal caches
@@ -76,32 +77,11 @@ module ActiveRecord
def marshal_dump
# if we get current version during initialization, it happens stack over flow.
@version = ActiveRecord::Migrator.current_version
- [@version] + [@columns, @columns_hash, @primary_keys, @tables].map { |val|
- Hash[val]
- }
+ [@version, @columns, @columns_hash, @primary_keys, @tables]
end
def marshal_load(array)
@version, @columns, @columns_hash, @primary_keys, @tables = array
- prepare_default_proc
- end
-
- private
-
- def prepare_default_proc
- @columns.default_proc = Proc.new do |h, table_name|
- h[table_name] = connection.columns(table_name)
- end
-
- @columns_hash.default_proc = Proc.new do |h, table_name|
- h[table_name] = Hash[columns(table_name).map { |col|
- [col.name, col]
- }]
- end
-
- @primary_keys.default_proc = Proc.new do |h, table_name|
- h[table_name] = table_exists?(table_name) ? connection.primary_key(table_name) : nil
- end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/type.rb b/activerecord/lib/active_record/connection_adapters/type.rb
index 395a4160a8..bab7a3ff7e 100644
--- a/activerecord/lib/active_record/connection_adapters/type.rb
+++ b/activerecord/lib/active_record/connection_adapters/type.rb
@@ -7,6 +7,7 @@ require 'active_record/connection_adapters/type/boolean'
require 'active_record/connection_adapters/type/date'
require 'active_record/connection_adapters/type/date_time'
require 'active_record/connection_adapters/type/decimal'
+require 'active_record/connection_adapters/type/decimal_without_scale'
require 'active_record/connection_adapters/type/float'
require 'active_record/connection_adapters/type/integer'
require 'active_record/connection_adapters/type/string'
diff --git a/activerecord/lib/active_record/connection_adapters/type/decimal_without_scale.rb b/activerecord/lib/active_record/connection_adapters/type/decimal_without_scale.rb
new file mode 100644
index 0000000000..e58c6e198d
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/decimal_without_scale.rb
@@ -0,0 +1,13 @@
+require 'active_record/connection_adapters/type/integer'
+
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class DecimalWithoutScale < Integer # :nodoc:
+ def type
+ :decimal
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index a607e9ac87..1262b2c291 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -573,15 +573,11 @@ WARNING
end
end
- def where!(opts = :chain, *rest) # :nodoc:
- if opts == :chain
- WhereChain.new(self)
- else
- references!(PredicateBuilder.references(opts)) if Hash === opts
+ def where!(opts, *rest) # :nodoc:
+ references!(PredicateBuilder.references(opts)) if Hash === opts
- self.where_values += build_where(opts, rest)
- self
- end
+ self.where_values += build_where(opts, rest)
+ self
end
# Allows you to change a previously set where condition for a given attribute, instead of appending to that condition.
diff --git a/activerecord/test/cases/connection_adapters/type_lookup_test.rb b/activerecord/test/cases/connection_adapters/type_lookup_test.rb
index 18df30faf5..3958c3bfff 100644
--- a/activerecord/test/cases/connection_adapters/type_lookup_test.rb
+++ b/activerecord/test/cases/connection_adapters/type_lookup_test.rb
@@ -77,12 +77,16 @@ module ActiveRecord
assert_lookup_type :integer, 'tinyint'
assert_lookup_type :integer, 'smallint'
assert_lookup_type :integer, 'bigint'
- assert_lookup_type :integer, 'decimal(2)'
- assert_lookup_type :integer, 'decimal(2,0)'
- assert_lookup_type :integer, 'numeric(2)'
- assert_lookup_type :integer, 'numeric(2,0)'
- assert_lookup_type :integer, 'number(2)'
- assert_lookup_type :integer, 'number(2,0)'
+ end
+
+ def test_decimal_without_scale
+ types = %w{decimal(2) decimal(2,0) numeric(2) numeric(2,0) number(2) number(2,0)}
+ types.each do |type|
+ cast_type = @connection.type_map.lookup(type)
+
+ assert_equal :decimal, cast_type.type
+ assert_equal 2, cast_type.type_cast(2.1)
+ end
end
private
diff --git a/activerecord/test/cases/relation/where_chain_test.rb b/activerecord/test/cases/relation/where_chain_test.rb
index c6decaad89..b9e69bdb08 100644
--- a/activerecord/test/cases/relation/where_chain_test.rb
+++ b/activerecord/test/cases/relation/where_chain_test.rb
@@ -99,7 +99,7 @@ module ActiveRecord
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::NotEqual
assert_equal 'ruby on rails', bind.last
end
-
+
def test_rewhere_with_one_condition
relation = Post.where(title: 'hello').where(title: 'world').rewhere(title: 'alone')
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 59675d744e..8a545e4386 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -180,10 +180,11 @@ module ActiveSupport #:nodoc:
Dependencies.load_missing_constant(from_mod, const_name)
end
- # Dependencies assumes the name of the module reflects the nesting (unless
- # it can be proven that is not the case), and the path to the file that
- # defines the constant. Anonymous modules cannot follow these conventions
- # and we assume therefore the user wants to refer to a top-level constant.
+ # We assume that the name of the module reflects the nesting
+ # (unless it can be proven that is not the case) and the path to the file
+ # that defines the constant. Anonymous modules cannot follow these
+ # conventions and therefore we assume that the user wants to refer to a
+ # top-level constant.
def guess_for_anonymous(const_name)
if Object.const_defined?(const_name)
raise NameError, "#{const_name} cannot be autoloaded from an anonymous class or module"
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 2dd00bed2e..7a9e1beb23 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -729,13 +729,47 @@ Rails will now prepend "/app1" when generating links.
#### Using Passenger
-Passenger makes it easy to run your application in a subdirectory. You can find
-the relevant configuration in the
-[passenger manual](http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rails_to_sub_uri).
+Passenger makes it easy to run your application in a subdirectory. You can find the relevant configuration in the [passenger manual](http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rails_to_sub_uri).
#### Using a Reverse Proxy
-TODO
+Deploying your application using a reverse proxy has definite advantages over traditional deploys. They allow you to have more control over your server by layering the components required by your application.
+
+Many modern web servers can be used as a proxy server to balance third-party elements such as caching servers or application servers.
+
+One such application server you can use is [Unicorn](http://unicorn.bogomips.org/) to run behind a reverse proxy.
+
+In this case, you would need to configure the proxy server (nginx, apache, etc) to accept connections from your application server (Unicorn). By default Unicorn will listen for TCP connections on port 8080, but you can change the port or configure it to use sockets instead.
+
+You can find more information in the [Unicorn readme](http://unicorn.bogomips.org/README.html) and understand the [philosophy](http://unicorn.bogomips.org/PHILOSOPHY.html) behind it.
+
+Once you've configured the application server, you must proxy requests to it by configuring your web server appropriately. For example your nginx config may include:
+
+```
+upstream application_server {
+ server 0.0.0.0:8080
+}
+
+server {
+ listen 80;
+ server_name localhost;
+
+ root /root/path/to/your_app/public;
+
+ try_files $uri/index.html $uri.html @app;
+
+ location @app {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $http_host;
+ proxy_redirect off;
+ proxy_pass http://application_server;
+ }
+
+ # some other configuration
+}
+```
+
+Be sure to read the [nginx documentation](http://nginx.org/en/docs/) for the most up-to-date information.
#### Considerations when deploying to a subdirectory
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index ba6a0feeef..9e7569465f 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -2,8 +2,7 @@
*Dan Kang*
-* Load database configuration from the first
- database.yml available in paths.
+* Load database configuration from the first `database.yml` available in paths.
*Pier-Olivier Thibault*
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 5a92ab3e95..b7da44ca2d 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -30,7 +30,12 @@ module Rails
protected
attr_reader :file_name
- alias :singular_name :file_name
+
+ # FIXME: We are avoiding to use alias because a bug on thor that make
+ # this method public and add it to the task list.
+ def singular_name
+ file_name
+ end
# Wrap block with namespace of current application
# if namespace exists and is not skipped
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 448b6f4845..5bdbd58097 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -16,7 +16,7 @@ source 'https://rubygems.org'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
-# Use unicorn as the app server
+# Use Unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment