aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile6
-rw-r--r--actionpack/CHANGELOG.md13
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb2
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb3
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb6
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb2
-rw-r--r--actionpack/test/controller/parameters/parameters_permit_test.rb14
-rw-r--r--actionpack/test/controller/send_file_test.rb2
-rw-r--r--actionview/test/actionpack/controller/layout_test.rb6
-rw-r--r--actionview/test/fixtures/developer.rb4
-rw-r--r--actionview/test/template/asset_tag_helper_test.rb8
-rw-r--r--activemodel/test/cases/helper.rb3
-rw-r--r--activerecord/CHANGELOG.md33
-rw-r--r--activerecord/lib/active_record/connection_adapters/connection_specification.rb90
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_handling.rb11
-rw-r--r--activerecord/lib/active_record/railtie.rb15
-rw-r--r--activerecord/lib/active_record/railties/databases.rake12
-rw-r--r--activerecord/lib/active_record/sanitization.rb9
-rw-r--r--activerecord/lib/active_record/tasks/database_tasks.rb19
-rw-r--r--activerecord/test/cases/adapter_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb14
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb18
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/json_test.rb10
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb7
-rw-r--r--activerecord/test/cases/connection_specification/resolver_test.rb58
-rw-r--r--activerecord/test/cases/multiple_db_test.rb2
-rw-r--r--activerecord/test/cases/transaction_isolation_test.rb4
-rw-r--r--activerecord/test/support/connection.rb4
-rw-r--r--guides/source/getting_started.md8
-rw-r--r--railties/CHANGELOG.md5
-rw-r--r--railties/lib/rails/commands/dbconsole.rb5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/secrets.yml10
-rw-r--r--railties/test/isolation/abstract_unit.rb21
50 files changed, 353 insertions, 191 deletions
diff --git a/Gemfile b/Gemfile
index 746dbac325..ebc4312f64 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,9 +36,9 @@ group :test do
gem 'ruby-prof', '~> 0.11.2'
end
- platforms :mri_19, :mri_20 do
- gem 'debugger'
- end
+ # platforms :mri_19, :mri_20 do
+ # gem 'debugger'
+ # end
gem 'benchmark-ips'
end
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index d696656521..3e3df19a84 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,7 @@
+* `ActionController::Parameters#permit!` permits hashes in array values.
+
+ *Xavier Noria*
+
* Converts hashes in arrays of unfiltered params to unpermitted params.
Fixes #13382
@@ -82,14 +86,15 @@
*Łukasz Strzałkowski*
-* Fix header `Content-Type: #<Mime::NullType:...>` in localized template.
+* Fix render of localized templates without an explicit format using wrong
+ content header and not passing correct formats to template due to the
+ introduction of the `NullType` for mimes.
- When localized template has no format in the template name,
- the response now has the default and correct `content-type`.
+ Templates like `hello.it.erb` were subject to this issue.
Fixes #13064.
- *Angelo Capilleri*
+ *Angelo Capilleri*, *Carlos Antonio da Silva*
* Try to escape each part of a url correctly when using a redirect route.
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 6f17e3fcd9..7be61d94c9 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -22,7 +22,7 @@ module AbstractController
def render(*args, &block)
options = _normalize_render(*args, &block)
self.response_body = render_to_body(options)
- _process_format(rendered_format)
+ _process_format(rendered_format) if rendered_format
self.response_body
end
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index 66d34f3b67..5c48b4ab98 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -34,8 +34,7 @@ module ActionController
def _process_format(format)
super
- # format is a Mime::NullType instance here then this condition can't be changed to `if format`
- self.content_type ||= format.to_s unless format.nil?
+ self.content_type ||= format.to_s
end
# Normalize arguments by catching blocks and setting them on :update.
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index 41be1b121e..48a916f2b1 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -157,8 +157,10 @@ module ActionController
# Person.new(params) # => #<Person id: nil, name: "Francesco">
def permit!
each_pair do |key, value|
- convert_hashes_to_parameters(key, value)
- self[key].permit! if self[key].respond_to? :permit!
+ value = convert_hashes_to_parameters(key, value)
+ Array.wrap(value).each do |_|
+ _.permit! if _.respond_to? :permit!
+ end
end
@permitted = true
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 346598b6de..c33ba201e1 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -50,7 +50,7 @@ module ActionDispatch
# GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first
#
def format(view_path = [])
- formats.first
+ formats.first || Mime::NullType.instance
end
def formats
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 2a8ff0a5d2..3d2dd2d632 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -28,7 +28,7 @@ module Mime
class << self
def [](type)
return type if type.is_a?(Type)
- Type.lookup_by_extension(type) || NullType.instance
+ Type.lookup_by_extension(type)
end
def fetch(type)
diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb
index 9c1828e9aa..33a91d72d9 100644
--- a/actionpack/test/controller/parameters/parameters_permit_test.rb
+++ b/actionpack/test/controller/parameters/parameters_permit_test.rb
@@ -8,9 +8,16 @@ class ParametersPermitTest < ActiveSupport::TestCase
end
setup do
- @params = ActionController::Parameters.new({ person: {
- age: "32", name: { first: "David", last: "Heinemeier Hansson" }
- }})
+ @params = ActionController::Parameters.new(
+ person: {
+ age: '32',
+ name: {
+ first: 'David',
+ last: 'Heinemeier Hansson'
+ },
+ addresses: [{city: 'Chicago', state: 'Illinois'}]
+ }
+ )
@struct_fields = []
%w(0 1 12).each do |number|
@@ -233,6 +240,7 @@ class ParametersPermitTest < ActiveSupport::TestCase
assert @params.permitted?
assert @params[:person].permitted?
assert @params[:person][:name].permitted?
+ assert @params[:person][:addresses][0].permitted?
end
test "permitted takes a default value when Parameters.permit_all_parameters is set" do
diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb
index 8ecc1c7d73..a4c84c29d7 100644
--- a/actionpack/test/controller/send_file_test.rb
+++ b/actionpack/test/controller/send_file_test.rb
@@ -144,7 +144,7 @@ class SendFileTest < ActionController::TestCase
}
@controller.headers = {}
- assert !@controller.send(:send_file_headers!, options)
+ assert_raise(ArgumentError) { @controller.send(:send_file_headers!, options) }
end
def test_send_file_headers_guess_type_from_extension
diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb
index 5dd23c4b31..b44f57a23e 100644
--- a/actionview/test/actionpack/controller/layout_test.rb
+++ b/actionview/test/actionpack/controller/layout_test.rb
@@ -215,12 +215,6 @@ class LayoutSetInResponseTest < ActionController::TestCase
end
end
-class RenderWithTemplateOptionController < LayoutTest
- def hello
- render :template => 'alt/hello'
- end
-end
-
class SetsNonExistentLayoutFile < LayoutTest
layout "nofile"
end
diff --git a/actionview/test/fixtures/developer.rb b/actionview/test/fixtures/developer.rb
index 4941463015..8b3f0a8039 100644
--- a/actionview/test/fixtures/developer.rb
+++ b/actionview/test/fixtures/developer.rb
@@ -4,7 +4,3 @@ class Developer < ActiveRecord::Base
has_many :topics, :through => :replies
accepts_nested_attributes_for :projects
end
-
-class DeVeLoPeR < ActiveRecord::Base
- self.table_name = "developers"
-end
diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb
index 541fca02d4..3ca71d3376 100644
--- a/actionview/test/template/asset_tag_helper_test.rb
+++ b/actionview/test/template/asset_tag_helper_test.rb
@@ -2,14 +2,6 @@ require 'zlib'
require 'abstract_unit'
require 'active_support/ordered_options'
-class FakeController
- attr_accessor :request
-
- def config
- @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config)
- end
-end
-
class AssetTagHelperTest < ActionView::TestCase
tests ActionView::Helpers::AssetTagHelper
diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb
index 7a63674757..522a7cebb4 100644
--- a/activemodel/test/cases/helper.rb
+++ b/activemodel/test/cases/helper.rb
@@ -7,4 +7,7 @@ require 'active_support/core_ext/string/access'
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
+# Disable available locale checks to avoid warnings running the test suite.
+I18n.enforce_available_locales = false
+
require 'active_support/testing/autorun'
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 6d130ab4d6..6b17d6b265 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,7 +1,36 @@
-* When connecting to a non-existant postgresql database, the error:
+* Deprecated use of string argument as a configuration lookup in `ActiveRecord::Base.establish_connection`. Instead, a symbol must be given.
+
+ *José Valim*
+
+* Fixed `update_column`, `update_columns`, and `update_all` to correctly serialize
+ values for `array`, `hstore` and `json` column types in PostgreSQL.
+
+ Fixes #12261.
+
+ *Tadas Tamosauskas*, *Carlos Antonio da Silva*
+
+* Do not consider PostgreSQL array columns as number or text columns.
+
+ The code uses these checks in several places to know what to do with a
+ particular column, for instance AR attribute query methods has a branch
+ like this:
+
+ if column.number?
+ !value.zero?
+ end
+
+ This should never be true for array columns, since it would be the same
+ as running [].zero?, which results in a NoMethodError exception.
+
+ Fixing this by ensuring that array columns in PostgreSQL never return
+ true for number?/text? checks.
+
+ *Carlos Antonio da Silva*
+
+* When connecting to a non-existant database, the error:
`ActiveRecord::NoDatabaseError` will now be raised. When being used with Rails
the error message will include information on how to create a database:
- `rake db:create`
+ `rake db:create`. Supported adapters: postgresql, mysql, mysql2, sqlite3
*Richard Schneeman*
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
index 66d7f04fc3..7e16156408 100644
--- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
@@ -16,38 +16,24 @@ module ActiveRecord
##
# Builds a ConnectionSpecification from user input
class Resolver # :nodoc:
- attr_reader :config, :klass, :configurations
+ attr_reader :configurations
- def initialize(config, configurations)
- @config = config
+ def initialize(configurations)
@configurations = configurations
end
- def spec
- case config
- when nil
- raise AdapterNotSpecified unless defined?(Rails.env)
- resolve_string_connection Rails.env
- when Symbol, String
- resolve_string_connection config.to_s
- when Hash
- resolve_hash_connection config
- end
- end
-
- private
- def resolve_string_connection(spec) # :nodoc:
- hash = configurations.fetch(spec) do |k|
- connection_url_to_hash(k)
+ def resolve(config)
+ if config
+ resolve_connection config
+ elsif defined?(Rails.env)
+ resolve_env_connection Rails.env.to_sym
+ else
+ raise AdapterNotSpecified
end
-
- raise(AdapterNotSpecified, "#{spec} database is not configured") unless hash
-
- resolve_hash_connection hash
end
- def resolve_hash_connection(spec) # :nodoc:
- spec = spec.symbolize_keys
+ def spec(config)
+ spec = resolve(config).symbolize_keys
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
@@ -61,12 +47,45 @@ module ActiveRecord
end
adapter_method = "#{spec[:adapter]}_connection"
-
ConnectionSpecification.new(spec, adapter_method)
end
- def connection_url_to_hash(url) # :nodoc:
- config = URI.parse url
+ private
+
+ def resolve_connection(spec) #:nodoc:
+ case spec
+ when Symbol, String
+ resolve_env_connection spec
+ when Hash
+ resolve_hash_connection spec
+ end
+ end
+
+ def resolve_env_connection(spec) # :nodoc:
+ # Rails has historically accepted a string to mean either
+ # an environment key or a url spec, so we have deprecated
+ # this ambiguous behaviour and in the future this function
+ # can be removed in favor of resolve_string_connection and
+ # resolve_symbol_connection.
+ if config = configurations[spec.to_s]
+ if spec.is_a?(String)
+ ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
+ "for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
+ end
+ resolve_connection(config)
+ elsif spec.is_a?(String)
+ resolve_string_connection(spec)
+ else
+ raise(AdapterNotSpecified, "#{spec} database is not configured")
+ end
+ end
+
+ def resolve_hash_connection(spec) # :nodoc:
+ spec
+ end
+
+ def resolve_string_connection(spec) # :nodoc:
+ config = URI.parse spec
adapter = config.scheme
adapter = "postgresql" if adapter == "postgres"
@@ -80,12 +99,12 @@ module ActiveRecord
config.path.sub(%r{^/},"")
end
- spec = { :adapter => adapter,
- :username => config.user,
- :password => config.password,
- :port => config.port,
- :database => database,
- :host => config.host }
+ spec = { "adapter" => adapter,
+ "username" => config.user,
+ "password" => config.password,
+ "port" => config.port,
+ "database" => database,
+ "host" => config.host }
spec.reject!{ |_,value| value.blank? }
@@ -94,8 +113,7 @@ module ActiveRecord
spec.map { |key,value| spec[key] = uri_parser.unescape(value) if value.is_a?(String) }
if config.query
- options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
-
+ options = Hash[config.query.split("&").map{ |pair| pair.split("=") }]
spec.merge!(options)
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index e790f731ea..6d8e994654 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -18,6 +18,12 @@ module ActiveRecord
client = Mysql2::Client.new(config)
options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config)
+ rescue Mysql2::Error => error
+ if error.message.include?("Unknown database")
+ raise ActiveRecord::NoDatabaseError.new(error.message)
+ else
+ raise error
+ end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 760f1435eb..7dbaa272a3 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -34,6 +34,12 @@ module ActiveRecord
default_flags |= Mysql::CLIENT_FOUND_ROWS if Mysql.const_defined?(:CLIENT_FOUND_ROWS)
options = [host, username, password, database, port, socket, default_flags]
ConnectionAdapters::MysqlAdapter.new(mysql, logger, options, config)
+ rescue Mysql::Error => error
+ if error.message.include?("Unknown database")
+ raise ActiveRecord::NoDatabaseError.new(error.message)
+ else
+ raise error
+ 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 95cd69d5ad..11a5eba464 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -46,7 +46,7 @@ module ActiveRecord
# PostgreSQL-specific extensions to column definitions in a table.
class PostgreSQLColumn < Column #:nodoc:
attr_accessor :array
- # Instantiates a new PostgreSQL column definition in a table.
+
def initialize(name, default, oid_type, sql_type = nil, null = true)
@oid_type = oid_type
default_value = self.class.extract_value_from_default(default)
@@ -62,6 +62,14 @@ module ActiveRecord
@default_function = default if has_default_function?(default_value, default)
end
+ def number?
+ !array && super
+ end
+
+ def text?
+ !array && super
+ end
+
# :stopdoc:
class << self
include ConnectionAdapters::PostgreSQLColumn::Cast
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index a02eda5603..92bb70ba53 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -31,6 +31,12 @@ module ActiveRecord
db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout]
ConnectionAdapters::SQLite3Adapter.new(db, logger, config)
+ rescue Errno::ENOENT => error
+ if error.message.include?("No such file or directory")
+ raise ActiveRecord::NoDatabaseError.new(error.message)
+ else
+ raise error
+ end
end
end
diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb
index a1943dfcb0..c4afadbd9b 100644
--- a/activerecord/lib/active_record/connection_handling.rb
+++ b/activerecord/lib/active_record/connection_handling.rb
@@ -32,11 +32,18 @@ module ActiveRecord
# "postgres://myuser:mypass@localhost/somedatabase"
# )
#
+ # In case <tt>ActiveRecord::Base.configurations</tt> is set (Rails
+ # automatically loads the contents of config/database.yml into it),
+ # a symbol can also be given as argument, representing a key in the
+ # configuration hash:
+ #
+ # ActiveRecord::Base.establish_connection(:production)
+ #
# The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError
# may be returned on an error.
def establish_connection(spec = ENV["DATABASE_URL"])
- resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new spec, configurations
- spec = resolver.spec
+ resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
+ spec = resolver.spec(spec)
unless respond_to?(spec.adapter_method)
raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index ff98c829f4..2c796f97e6 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -43,11 +43,24 @@ module ActiveRecord
namespace :db do
task :load_config do
ActiveRecord::Tasks::DatabaseTasks.db_dir = Rails.application.config.paths["db"].first
- ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
ActiveRecord::Tasks::DatabaseTasks.migrations_paths = Rails.application.paths['db/migrate'].to_a
ActiveRecord::Tasks::DatabaseTasks.fixtures_path = File.join Rails.root, 'test', 'fixtures'
ActiveRecord::Tasks::DatabaseTasks.root = Rails.root
+ configuration = if ENV["DATABASE_URL"]
+ { Rails.env => ENV["DATABASE_URL"] }
+ else
+ Rails.application.config.database_configuration || {}
+ end
+
+ resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(configuration)
+
+ configuration.each do |key, value|
+ configuration[key] = resolver.resolve(value) if value
+ end
+
+ ActiveRecord::Tasks::DatabaseTasks.database_configuration = configuration
+
if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
if engine.paths['db/migrate'].existent
ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index 0fdfed991c..90dfc177e5 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -14,11 +14,7 @@ db_namespace = namespace :db do
desc 'Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all databases in the config)'
task :create => [:load_config] do
- if ENV['DATABASE_URL']
- ActiveRecord::Tasks::DatabaseTasks.create_database_url
- else
- ActiveRecord::Tasks::DatabaseTasks.create_current
- end
+ ActiveRecord::Tasks::DatabaseTasks.create_current
end
namespace :drop do
@@ -29,11 +25,7 @@ db_namespace = namespace :db do
desc 'Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)'
task :drop => [:load_config] do
- if ENV['DATABASE_URL']
- ActiveRecord::Tasks::DatabaseTasks.drop_database_url
- else
- ActiveRecord::Tasks::DatabaseTasks.drop_current
- end
+ ActiveRecord::Tasks::DatabaseTasks.drop_current
end
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb
index cab8fd745a..dacaec26b7 100644
--- a/activerecord/lib/active_record/sanitization.rb
+++ b/activerecord/lib/active_record/sanitization.rb
@@ -100,8 +100,9 @@ module ActiveRecord
# { status: nil, group_id: 1 }
# # => "status = NULL , group_id = 1"
def sanitize_sql_hash_for_assignment(attrs, table)
+ c = connection
attrs.map do |attr, value|
- "#{connection.quote_table_name_for_assignment(table, attr)} = #{quote_bound_value(value)}"
+ "#{c.quote_table_name_for_assignment(table, attr)} = #{quote_bound_value(value, c, columns_hash[attr.to_s])}"
end.join(', ')
end
@@ -152,8 +153,10 @@ module ActiveRecord
end
end
- def quote_bound_value(value, c = connection) #:nodoc:
- if value.respond_to?(:map) && !value.acts_like?(:string)
+ def quote_bound_value(value, c = connection, column = nil) #:nodoc:
+ if column
+ c.quote(value, column)
+ elsif value.respond_to?(:map) && !value.acts_like?(:string)
if value.respond_to?(:empty?) && value.empty?
c.quote(nil)
else
diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb
index be7d496d15..06592eece2 100644
--- a/activerecord/lib/active_record/tasks/database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/database_tasks.rb
@@ -56,11 +56,7 @@ module ActiveRecord
if options.has_key?(:config)
@current_config = options[:config]
else
- @current_config ||= if ENV['DATABASE_URL']
- database_url_config
- else
- ActiveRecord::Base.configurations[options[:env]]
- end
+ @current_config ||= ActiveRecord::Base.configurations[options[:env]]
end
end
@@ -85,10 +81,6 @@ module ActiveRecord
ActiveRecord::Base.establish_connection environment
end
- def create_database_url
- create database_url_config
- end
-
def drop(*arguments)
configuration = arguments.first
class_for_adapter(configuration['adapter']).new(*arguments).drop
@@ -107,10 +99,6 @@ module ActiveRecord
}
end
- def drop_database_url
- drop database_url_config
- end
-
def charset_current(environment = env)
charset ActiveRecord::Base.configurations[environment]
end
@@ -165,11 +153,6 @@ module ActiveRecord
private
- def database_url_config
- @database_url_config ||=
- ConnectionAdapters::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
- end
-
def class_for_adapter(adapter)
key = @tasks.keys.detect { |pattern| adapter[pattern] }
unless key
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 34be68a97f..2bb2481fdb 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -191,7 +191,7 @@ module ActiveRecord
end
def setup
- Klass.establish_connection 'arunit'
+ Klass.establish_connection :arunit
@connection = Klass.connection
end
diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
index a2c933d96a..a8b5cfb0cd 100644
--- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
@@ -16,6 +16,20 @@ module ActiveRecord
eosql
end
+ def test_bad_connection_mysql
+ assert_raise ActiveRecord::NoDatabaseError do
+ connection = ActiveRecord::Base.mysql_connection(adapter: "mysql", database: "should_not_exist-cinco-dog-db")
+ connection.exec_query('drop table if exists ex')
+ end
+ end
+
+ def test_bad_connection_mysql2
+ assert_raise ActiveRecord::NoDatabaseError do
+ connection = ActiveRecord::Base.mysql2_connection(adapter: "mysql2", database: "should_not_exist-cinco-dog-db")
+ connection.exec_query('drop table if exists ex')
+ end
+ end
+
def test_valid_column
column = @conn.columns('ex').find { |col| col.name == 'id' }
assert @conn.valid_type?(column.type)
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 114d5b6cc6..d71e2aa2bb 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -26,6 +26,12 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
def test_column
assert_equal :string, @column.type
assert @column.array
+ assert_not @column.text?
+
+ ratings_column = PgArray.columns_hash['ratings']
+ assert_equal :integer, ratings_column.type
+ assert ratings_column.array
+ assert_not ratings_column.number?
end
def test_change_column_with_array
@@ -50,8 +56,6 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
end
def test_type_cast_array
- assert @column
-
data = '{1,2,3}'
oid_type = @column.instance_variable_get('@oid_type').subtype
# we are getting the instance variable in this test, but in the
@@ -124,6 +128,16 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]", record.attribute_for_inspect(:ratings))
end
+ def test_update_all
+ pg_array = PgArray.create! tags: ["one", "two", "three"]
+
+ PgArray.update_all tags: ["four", "five"]
+ assert_equal ["four", "five"], pg_array.reload.tags
+
+ PgArray.update_all tags: []
+ assert_equal [], pg_array.reload.tags
+ end
+
private
def assert_cycle field, array
# test creation
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 2845413575..6df5d8f533 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -206,6 +206,16 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
def test_multiline
assert_cycle("a\nb" => "c\nd")
end
+
+ def test_update_all
+ hstore = Hstore.create! tags: { "one" => "two" }
+
+ Hstore.update_all tags: { "three" => "four" }
+ assert_equal({ "three" => "four" }, hstore.reload.tags)
+
+ Hstore.update_all tags: { }
+ assert_equal({ }, hstore.reload.tags)
+ end
end
private
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb
index c33c7ef968..01e7334aad 100644
--- a/activerecord/test/cases/adapters/postgresql/json_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/json_test.rb
@@ -121,4 +121,14 @@ class PostgresqlJSONTest < ActiveRecord::TestCase
x = JsonDataType.first
assert_equal "640×1136", x.resolution
end
+
+ def test_update_all
+ json = JsonDataType.create! payload: { "one" => "two" }
+
+ JsonDataType.update_all payload: { "three" => "four" }
+ assert_equal({ "three" => "four" }, json.reload.payload)
+
+ JsonDataType.update_all payload: { }
+ assert_equal({ }, json.reload.payload)
+ end
end
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 48ffbd1103..0598ff25f8 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -26,6 +26,13 @@ module ActiveRecord
ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber)
end
+ def test_bad_connection
+ assert_raise ActiveRecord::NoDatabaseError do
+ connection = ActiveRecord::Base.sqlite3_connection(adapter: "sqlite3", database: "/tmp/should/_not/_exist/-cinco-dog.db")
+ connection.exec_query('drop table if exists ex')
+ end
+ end
+
def test_connect_with_url
original_connection = ActiveRecord::Base.remove_connection
tf = Tempfile.open 'whatever'
diff --git a/activerecord/test/cases/connection_specification/resolver_test.rb b/activerecord/test/cases/connection_specification/resolver_test.rb
index 528de07eab..ba8440a16b 100644
--- a/activerecord/test/cases/connection_specification/resolver_test.rb
+++ b/activerecord/test/cases/connection_specification/resolver_test.rb
@@ -4,68 +4,74 @@ module ActiveRecord
module ConnectionAdapters
class ConnectionSpecification
class ResolverTest < ActiveRecord::TestCase
- def resolve(spec)
- Resolver.new(spec, {}).spec.config
+ def resolve(spec, config={})
+ Resolver.new(config).resolve(spec)
+ end
+
+ def spec(spec, config={})
+ Resolver.new(config).spec(spec)
end
def test_url_invalid_adapter
- assert_raises(LoadError) do
- resolve 'ridiculous://foo?encoding=utf8'
+ error = assert_raises(LoadError) do
+ spec 'ridiculous://foo?encoding=utf8'
end
+
+ assert_match "Could not load 'active_record/connection_adapters/ridiculous_adapter'", error.message
end
# The abstract adapter is used simply to bypass the bit of code that
# checks that the adapter file can be required in.
+ def test_url_from_environment
+ spec = resolve :production, 'production' => 'abstract://foo?encoding=utf8'
+ assert_equal({
+ "adapter" => "abstract",
+ "host" => "foo",
+ "encoding" => "utf8" }, spec)
+ end
+
def test_url_host_no_db
spec = resolve 'abstract://foo?encoding=utf8'
assert_equal({
- adapter: "abstract",
- host: "foo",
- encoding: "utf8" }, spec)
+ "adapter" => "abstract",
+ "host" => "foo",
+ "encoding" => "utf8" }, spec)
end
def test_url_host_db
spec = resolve 'abstract://foo/bar?encoding=utf8'
assert_equal({
- adapter: "abstract",
- database: "bar",
- host: "foo",
- encoding: "utf8" }, spec)
+ "adapter" => "abstract",
+ "database" => "bar",
+ "host" => "foo",
+ "encoding" => "utf8" }, spec)
end
def test_url_port
spec = resolve 'abstract://foo:123?encoding=utf8'
assert_equal({
- adapter: "abstract",
- port: 123,
- host: "foo",
- encoding: "utf8" }, spec)
+ "adapter" => "abstract",
+ "port" => 123,
+ "host" => "foo",
+ "encoding" => "utf8" }, spec)
end
def test_encoded_password
password = 'am@z1ng_p@ssw0rd#!'
encoded_password = URI.encode_www_form_component(password)
spec = resolve "abstract://foo:#{encoded_password}@localhost/bar"
- assert_equal password, spec[:password]
- end
-
- def test_descriptive_error_message_when_adapter_is_missing
- error = assert_raise(LoadError) do
- resolve(adapter: 'non-existing')
- end
-
- assert_match "Could not load 'active_record/connection_adapters/non-existing_adapter'", error.message
+ assert_equal password, spec["password"]
end
def test_url_host_db_for_sqlite3
spec = resolve 'sqlite3://foo:bar@dburl:9000/foo_test'
- assert_equal('/foo_test', spec[:database])
+ assert_equal('/foo_test', spec["database"])
end
def test_url_host_memory_db_for_sqlite3
spec = resolve 'sqlite3://foo:bar@dburl:9000/:memory:'
- assert_equal(':memory:', spec[:database])
+ assert_equal(':memory:', spec["database"])
end
end
end
diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb
index 2e386a172a..3831de6ae3 100644
--- a/activerecord/test/cases/multiple_db_test.rb
+++ b/activerecord/test/cases/multiple_db_test.rb
@@ -101,7 +101,7 @@ class MultipleDbTest < ActiveRecord::TestCase
College.first.courses.first
end
ensure
- ActiveRecord::Base.establish_connection 'arunit'
+ ActiveRecord::Base.establish_connection :arunit
end
end
end
diff --git a/activerecord/test/cases/transaction_isolation_test.rb b/activerecord/test/cases/transaction_isolation_test.rb
index 84c16fb109..f89c26532d 100644
--- a/activerecord/test/cases/transaction_isolation_test.rb
+++ b/activerecord/test/cases/transaction_isolation_test.rb
@@ -28,8 +28,8 @@ if ActiveRecord::Base.connection.supports_transaction_isolation?
end
setup do
- Tag.establish_connection 'arunit'
- Tag2.establish_connection 'arunit'
+ Tag.establish_connection :arunit
+ Tag2.establish_connection :arunit
Tag.destroy_all
end
diff --git a/activerecord/test/support/connection.rb b/activerecord/test/support/connection.rb
index 196b3a9493..d11fd9cfc1 100644
--- a/activerecord/test/support/connection.rb
+++ b/activerecord/test/support/connection.rb
@@ -15,7 +15,7 @@ module ARTest
puts "Using #{connection_name}"
ActiveRecord::Base.logger = ActiveSupport::Logger.new("debug.log", 0, 100 * 1024 * 1024)
ActiveRecord::Base.configurations = connection_config
- ActiveRecord::Base.establish_connection 'arunit'
- ARUnit2Model.establish_connection 'arunit2'
+ ActiveRecord::Base.establish_connection :arunit
+ ARUnit2Model.establish_connection :arunit2
end
end
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 279a977f6f..afb3bb22bf 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -86,7 +86,7 @@ current version of Ruby installed:
```bash
$ ruby -v
-ruby 2.0.0p247
+ruby 2.0.0p353
```
To install Rails, use the `gem install` command provided by RubyGems:
@@ -1703,8 +1703,8 @@ Deleting Comments
-----------------
Another important feature of a blog is being able to delete spam comments. To do
-this, we need to implement a link of some sort in the view and a `DELETE` action
-in the `CommentsController`.
+this, we need to implement a link of some sort in the view and a `destroy`
+action in the `CommentsController`.
So first, let's add the delete link in the
`app/views/comments/_comment.html.erb` partial:
@@ -1729,7 +1729,7 @@ So first, let's add the delete link in the
Clicking this new "Destroy Comment" link will fire off a `DELETE
/posts/:post_id/comments/:id` to our `CommentsController`, which can then use
-this to find the comment we want to delete, so let's add a destroy action to our
+this to find the comment we want to delete, so let's add a `destroy` action to our
controller (`app/controllers/comments_controller.rb`):
```ruby
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index aa26017bda..a83c2b2355 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Configure `secrets.yml` and `database.yml` to read configuration
+ from the system environment by default for production.
+
+ *José Valim*
+
* `config.assets.raise_runtime_errors` is set to true by default
This option has been introduced in
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
index 847447fdad..c265ed8f36 100644
--- a/railties/lib/rails/commands/dbconsole.rb
+++ b/railties/lib/rails/commands/dbconsole.rb
@@ -83,9 +83,8 @@ module Rails
@config ||= begin
require APP_PATH
ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(
- ENV['DATABASE_URL'],
- (Rails.application.config.database_configuration || {})
- ).spec.config.stringify_keys
+ Rails.application.config.database_configuration || {}
+ ).resolve(ENV["DATABASE_URL"])
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
index c6dfd50d40..334d2ba51c 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
@@ -23,6 +23,6 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index fe53cd0ea2..0a2dc1b19e 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
@@ -61,6 +61,6 @@ test:
<<: *default
database: <%= app_name[0,4] %>_tst
-production:
- <<: *default
- database: <%= app_name[0,8] %>
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
index be1dae332f..cda6bcab06 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
@@ -53,6 +53,6 @@ test:
<<: *default
url: jdbc:db://localhost/<%= app_name %>_test
-production:
- <<: *default
- url: jdbc:db://localhost/<%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
index 26e2a5976c..b316b3ade1 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -26,6 +26,6 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
index 2776ba477f..d76632f0ac 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
@@ -42,6 +42,6 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
index 28c36eb82f..4aaa97b104 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
@@ -18,6 +18,6 @@ test:
<<: *default
database: db/test.sqlite3
-production:
- <<: *default
- database: db/production.sqlite3
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index 3fc7ce28a1..28a5418b49 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
@@ -32,6 +32,10 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Avoid production credentials in the repository,
+# instead read the configuration from the environment.
+#
+# Example:
+# mysql2://myuser:mypass@localhost/somedatabase
+#
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
index d5b52c969b..31abbe8ba6 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
@@ -32,6 +32,6 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
index bdf53726c0..7a7a8c08e0 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
@@ -59,6 +59,10 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+#
+# Example:
+# postgres://myuser:mypass@localhost/somedatabase
+#
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
index 1c1a37ca8d..d8b0b61e14 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
@@ -20,6 +20,10 @@ test:
<<: *default
database: db/test.sqlite3
-production:
- <<: *default
- database: db/production.sqlite3
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+#
+# Example:
+# sqlite3://myuser:mypass@localhost/somedatabase
+#
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
index 4855f66c0d..c270497879 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
@@ -42,6 +42,6 @@ test:
<<: *default
database: <%= app_name %>_test
-production:
- <<: *default
- database: <%= app_name %>_production
+# Do not keep production credentials in the repository,
+# instead read the configuration from the environment.
+production: <%%= ENV["RAILS_DATABASE_URL"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
index b32e4bf2a6..6e2c45e119 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
@@ -16,11 +16,7 @@ development:
test:
secret_key_base: <%= app_secret %>
-# This YAML file is processed by ERB first (as others). In particular the
-# production environment can set the secret via an environment variable
-# this way:
-#
-# secret_key_base: <%%= ENV['SECRET_KEY_BASE'] %>
-#
+# Do not keep production secrets in the repository,
+# instead read values from the environment.
production:
- secret_key_base: <%= app_secret %>
+ secret_key_base: <%%= ENV["RAILS_SECRET_KEY_BASE"] %>
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 362c2c510a..bf0fdea89a 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -117,7 +117,26 @@ module TestHelpers
end
end
+ File.open("#{app_path}/config/database.yml", "w") do |f|
+ f.puts <<-YAML
+ default: &default
+ adapter: sqlite3
+ pool: 5
+ timeout: 5000
+ development:
+ <<: *default
+ database: db/development.sqlite3
+ test:
+ <<: *default
+ database: db/test.sqlite3
+ production:
+ <<: *default
+ database: db/production.sqlite3
+ YAML
+ end
+
add_to_config <<-RUBY
+ secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
config.eager_load = false
config.session_store :cookie_store, key: "_myapp_session"
config.active_support.deprecation = :log
@@ -137,8 +156,8 @@ module TestHelpers
require "action_view/railtie"
app = Class.new(Rails::Application)
- app.config.eager_load = false
app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
+ app.config.eager_load = false
app.config.session_store :cookie_store, key: "_myapp_session"
app.config.active_support.deprecation = :log