diff options
Diffstat (limited to 'railties')
22 files changed, 268 insertions, 40 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index f267be5eb8..ff6dcac465 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,17 @@ +* Generated migrations add the appropriate foreign key constraints to + references. + + *Derek Prior* + +* Deprecate different default for `log_level` in production. + + *Godfrey Chan*, *Matthew Draper* + +* Generated `.gitignore` excludes the whole `log/` directory, not only + `*.log` files. + + *ShunsukeAida* + * `Rails::Paths::Path.unshift` now has the same interface as `Array.unshift`. *Igor Kapkov* diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb index 1a2613a8d0..b01cdce6ea 100644 --- a/railties/lib/rails/commands/dbconsole.rb +++ b/railties/lib/rails/commands/dbconsole.rb @@ -74,6 +74,21 @@ module Rails find_cmd_and_exec('sqlplus', logon) + when "sqlserver" + args = [] + + args += ["-D", "#{config['database']}"] if config['database'] + args += ["-U", "#{config['username']}"] if config['username'] + args += ["-P", "#{config['password']}"] if config['password'] + + if config['host'] + host_arg = "#{config['host']}" + host_arg << ":#{config['port']}" if config['port'] + args += ["-S", host_arg] + end + + find_cmd_and_exec("sqsh", *args) + else abort "Unknown command-line client for #{config['database']}. Submit a Rails patch to add support!" end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index f5d7dede66..f99cec04c5 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -18,11 +18,11 @@ module Rails # This will put the <tt>Magical::Unicorns</tt> middleware on the end of the stack. # You can use +insert_before+ if you wish to add a middleware before another: # - # config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns + # config.middleware.insert_before Rack::Head, Magical::Unicorns # # There's also +insert_after+ which will insert a middleware after another: # - # config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns + # config.middleware.insert_after Rack::Head, Magical::Unicorns # # Middlewares can also be completely swapped out and replaced with others: # diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 023ea98145..4b7da32208 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -351,7 +351,7 @@ module Rails base.called_from = begin call_stack = if Kernel.respond_to?(:caller_locations) - caller_locations.map(&:path) + caller_locations.map(&:absolute_path) else # Remove the line number from backtraces making sure we don't leave anything behind caller.map { |p| p.sub(/:\d+.*/, '') } diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 5f8c33c713..0823b0cc46 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -195,11 +195,9 @@ module Rails def rails_gemfile_entry if options.dev? - [GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH), - GemfileEntry.github('rails-dom-testing', 'rails/rails-dom-testing')] + [GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH)] elsif options.edge? - [GemfileEntry.github('rails', 'rails/rails'), - GemfileEntry.github('rails-dom-testing', 'rails/rails-dom-testing')] + [GemfileEntry.github('rails', 'rails/rails')] else [GemfileEntry.version('rails', Rails::VERSION::STRING, @@ -239,8 +237,6 @@ module Rails gems = [] if options.dev? || options.edge? - gems << GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails', - 'Use edge version of sprockets-rails') gems << GemfileEntry.github('sass-rails', 'rails/sass-rails', 'Use SCSS for stylesheets') else @@ -280,14 +276,8 @@ module Rails [] else gems = [coffee_gemfile_entry, javascript_runtime_gemfile_entry] - - if options[:javascript] == 'jquery' - gems << GemfileEntry.version('jquery-rails', '~> 4.0.0.beta2', - 'Use jQuery as the JavaScript library') - else - gems << GemfileEntry.version("#{options[:javascript]}-rails", nil, - "Use #{options[:javascript]} as the JavaScript library") - end + gems << GemfileEntry.version("#{options[:javascript]}-rails", nil, + "Use #{options[:javascript]} as the JavaScript library") unless options[:skip_turbolinks] gems << GemfileEntry.version("turbolinks", nil, diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb index 66b17bd10e..f9b3658ae7 100644 --- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb +++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb @@ -1,8 +1,29 @@ -require 'rails/generators/erb/controller/controller_generator' +require 'rails/generators/erb' module Erb # :nodoc: module Generators # :nodoc: - class MailerGenerator < ControllerGenerator # :nodoc: + class MailerGenerator < Base # :nodoc: + argument :actions, type: :array, default: [], banner: "method method" + + def copy_view_files + view_base_path = File.join("app/views", class_path, file_name) + empty_directory view_base_path + + formats.each do |format| + layout_path = File.join("app/views/layouts", filename_with_extensions("mailer", format)) + template filename_with_extensions(:layout, format), layout_path + end + + actions.each do |action| + @action = action + + formats.each do |format| + @path = File.join(view_base_path, filename_with_extensions(action, format)) + template filename_with_extensions(:view, format), @path + end + end + end + protected def formats diff --git a/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb b/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb new file mode 100644 index 0000000000..93110e74ad --- /dev/null +++ b/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb @@ -0,0 +1,5 @@ +<html> + <body> + <%%= yield %> + </body> +</html> diff --git a/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb b/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb new file mode 100644 index 0000000000..6363733e6e --- /dev/null +++ b/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb @@ -0,0 +1 @@ +<%%= yield %> diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 5961f7515c..7027312aa9 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -32,7 +32,7 @@ group :development, :test do <%- end -%> # Access an IRB console on exception pages or by using <%%= console %> in views - gem 'web-console', '~> 2.0.0.beta4' + gem 'web-console', '~> 2.0' <%- if spring_install? %> # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt index 07ea09cdbd..c1a77944e8 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt @@ -2,7 +2,7 @@ // listed below. // // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. // // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // compiled file. diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css index a443db3401..f9cd5b3483 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css @@ -3,7 +3,7 @@ * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the bottom of the * compiled file so the styles you add here take precedence over styles defined in any styles diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore index 8775e5e235..7c6f2098b8 100644 --- a/railties/lib/rails/generators/rails/app/templates/gitignore +++ b/railties/lib/rails/generators/rails/app/templates/gitignore @@ -14,5 +14,6 @@ <% end -%> # Ignore all logfiles and tempfiles. -/log/*.log +/log/* +!/log/.keep /tmp diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js index 5bc2e1c8b5..c28e5badc6 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js @@ -2,7 +2,7 @@ // listed below. // // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. // // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // compiled file. diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css index a443db3401..f9cd5b3483 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css @@ -3,7 +3,7 @@ * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the bottom of the * compiled file so the styles you add here take precedence over styles defined in any styles diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 391139d7f8..1f97807f8c 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -967,6 +967,36 @@ module ApplicationTests end end + test "Blank config.log_level is not deprecated for non-production environment" do + with_rails_env "development" do + assert_not_deprecated do + make_basic_app do |app| + app.config.log_level = nil + end + end + end + end + + test "Blank config.log_level is deprecated for the production environment" do + with_rails_env "production" do + assert_deprecated(/log_level/) do + make_basic_app do |app| + app.config.log_level = nil + end + end + end + end + + test "Not blank config.log_level is not deprecated for the production environment" do + with_rails_env "production" do + assert_not_deprecated do + make_basic_app do |app| + app.config.log_level = :info + end + end + end + end + test "config.log_level with custom logger" do make_basic_app do |app| app.config.logger = Logger.new(STDOUT) diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 524c70aad2..0a5873bcbf 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -175,15 +175,6 @@ module ApplicationTests db_test_load_structure end - test 'db:test deprecation' do - require "#{app_path}/config/environment" - Dir.chdir(app_path) do - output = `bundle exec rake db:migrate db:test:prepare 2>&1` - assert_equal "WARNING: db:test:prepare is deprecated. The Rails test helper now maintains " \ - "your test schema automatically, see the release notes for details.\n", output - end - end - test 'db:setup loads schema and seeds database' do begin @old_rails_env = ENV["RAILS_ENV"] diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb index c724c867ec..c7132837b1 100644 --- a/railties/test/application/test_test.rb +++ b/railties/test/application/test_test.rb @@ -193,6 +193,98 @@ module ApplicationTests assert_successful_test_run('models/user_test.rb') end + # TODO: would be nice if we could detect the schema change automatically. + # For now, the user has to synchronize the schema manually. + # This test-case serves as a reminder for this use-case. + test "manually synchronize test schema after rollback" do + output = script('generate model user name:string') + version = output.match(/(\d+)_create_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + + class UserTest < ActiveSupport::TestCase + test "user" do + assert_equal ["id", "name"], User.columns_hash.keys + end + end + RUBY + app_file 'db/schema.rb', <<-RUBY + ActiveRecord::Schema.define(version: #{version}) do + create_table :users do |t| + t.string :name + end + end + RUBY + + assert_successful_test_run "models/user_test.rb" + + # Simulate `db:rollback` + edit of the migration file + `db:migrate` + app_file 'db/schema.rb', <<-RUBY + ActiveRecord::Schema.define(version: #{version}) do + create_table :users do |t| + t.string :name + t.integer :age + end + end + RUBY + + assert_successful_test_run "models/user_test.rb" + + Dir.chdir(app_path) { `bin/rake db:test:prepare` } + + assert_unsuccessful_run "models/user_test.rb", <<-ASSERTION +Expected: ["id", "name"] + Actual: ["id", "name", "age"] + ASSERTION + end + + test "hooks for plugins" do + output = script('generate model user name:string') + version = output.match(/(\d+)_create_users\.rb/)[1] + + app_file 'lib/tasks/hooks.rake', <<-RUBY + task :before_hook do + has_user_table = ActiveRecord::Base.connection.table_exists?('users') + puts "before: " + has_user_table.to_s + end + + task :after_hook do + has_user_table = ActiveRecord::Base.connection.table_exists?('users') + puts "after: " + has_user_table.to_s + end + + Rake::Task["db:test:prepare"].enhance [:before_hook] do + Rake::Task[:after_hook].invoke + end + RUBY + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon" + end + end + RUBY + + # Simulate `db:migrate` + app_file 'db/schema.rb', <<-RUBY + ActiveRecord::Schema.define(version: #{version}) do + create_table :users do |t| + t.string :name + end + end + RUBY + + output = assert_successful_test_run "models/user_test.rb" + assert_includes output, "before: false\nafter: true" + + # running tests again won't trigger a schema update + output = assert_successful_test_run "models/user_test.rb" + assert_not_includes output, "before:" + assert_not_includes output, "after:" + end + private def assert_unsuccessful_run(name, message) result = run_test_file(name) @@ -208,7 +300,7 @@ module ApplicationTests end def run_test_file(name, options = {}) - ruby '-Itest', "#{app_path}/test/#{name}", options + ruby '-Itest', "#{app_path}/test/#{name}", options.deep_merge(env: {"RAILS_ENV" => "test"}) end def ruby(*args) diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index 25649881eb..bab15ce172 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -8,8 +8,18 @@ class MailerGeneratorTest < Rails::Generators::TestCase def test_mailer_skeleton_is_created run_generator assert_file "app/mailers/notifier.rb" do |mailer| - assert_match(/class Notifier < ActionMailer::Base/, mailer) + assert_match(/class Notifier < ApplicationMailer/, mailer) + assert_no_match(/default from: "from@example.com"/, mailer) + assert_no_match(/layout :mailer_notifier/, mailer) + end + end + + def test_application_mailer_skeleton_is_created + run_generator + assert_file "app/mailers/application_mailer.rb" do |mailer| + assert_match(/class ApplicationMailer < ActionMailer::Base/, mailer) assert_match(/default from: "from@example.com"/, mailer) + assert_match(/layout 'mailer'/, mailer) end end @@ -77,6 +87,10 @@ class MailerGeneratorTest < Rails::Generators::TestCase assert_match(%r(\sapp/views/notifier/bar\.text\.erb), view) assert_match(/<%= @greeting %>/, view) end + + assert_file "app/views/layouts/mailer.text.erb" do |view| + assert_match(/<%= yield %>/, view) + end end def test_invokes_default_html_template_engine @@ -90,11 +104,17 @@ class MailerGeneratorTest < Rails::Generators::TestCase assert_match(%r(\sapp/views/notifier/bar\.html\.erb), view) assert_match(/<%= @greeting %>/, view) end + + assert_file "app/views/layouts/mailer.html.erb" do |view| + assert_match(%r{<html>\n <body>\n <%= yield %>\n </body>\n</html>}, view) + end end def test_invokes_default_template_engine_even_with_no_action run_generator ["notifier"] assert_file "app/views/notifier" + assert_file "app/views/layouts/mailer.text.erb" + assert_file "app/views/layouts/mailer.html.erb" end def test_logs_if_the_template_engine_cannot_be_found @@ -105,7 +125,7 @@ class MailerGeneratorTest < Rails::Generators::TestCase def test_mailer_with_namedspaced_mailer run_generator ["Farm::Animal", "moos"] assert_file "app/mailers/farm/animal.rb" do |mailer| - assert_match(/class Farm::Animal < ActionMailer::Base/, mailer) + assert_match(/class Farm::Animal < ApplicationMailer/, mailer) assert_match(/en\.farm\.animal\.moos\.subject/, mailer) end assert_file "test/mailers/previews/farm/animal_preview.rb" do |preview| diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb index 72f5fe29ca..c2c8e2abad 100644 --- a/railties/test/generators/migration_generator_test.rb +++ b/railties/test/generators/migration_generator_test.rb @@ -85,6 +85,18 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_remove_migration_with_references_removes_foreign_keys + migration = "remove_references_from_books" + run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/remove_foreign_key :books, :authors/, change) + assert_no_match(/remove_foreign_key :books, :distributors/, change) + end + end + end + def test_add_migration_with_attributes_and_indices migration = "add_title_with_index_and_body_to_posts" run_generator [migration, "title:string:index", "body:text", "user_id:integer:uniq"] @@ -171,6 +183,18 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_add_migration_with_references_adds_foreign_keys + migration = "add_references_to_books" + run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/add_foreign_key :books, :authors/, change) + assert_no_match(/add_foreign_key :books, :distributors/, change) + end + end + end + def test_create_join_table_migration migration = "add_media_join_table" run_generator [migration, "artist_id", "musics:uniq"] @@ -205,7 +229,7 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end end - + def test_properly_identifies_usage_file assert generator_class.send(:usage_path) end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index c78597c81b..ac7a0acf6b 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -407,6 +407,27 @@ class ModelGeneratorTest < Rails::Generators::TestCase end end + def test_foreign_key_is_added_for_references + run_generator ["account", "supplier:belongs_to", "user:references"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_match(/add_foreign_key :accounts, :suppliers/, up) + assert_match(/add_foreign_key :accounts, :users/, up) + end + end + end + + def test_foreign_key_is_skipped_for_polymorphic_references + run_generator ["account", "supplier:belongs_to{polymorphic}"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_no_match(/add_foreign_key :accounts, :suppliers/, up) + end + end + end + private def assert_generated_fixture(path, parsed_contents) fixture_file = File.new File.expand_path(path, destination_root) diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index 7eeb084eab..6075805152 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -148,8 +148,8 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase run_generator assert_file "app/mailers/test_app/notifier.rb" do |mailer| assert_match(/module TestApp/, mailer) - assert_match(/class Notifier < ActionMailer::Base/, mailer) - assert_match(/default from: "from@example.com"/, mailer) + assert_match(/class Notifier < ApplicationMailer/, mailer) + assert_no_match(/default from: "from@example.com"/, mailer) end end diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index bf2992005b..9ad0ec0d34 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -143,6 +143,7 @@ module TestHelpers config.active_support.deprecation = :log config.active_support.test_order = :random config.action_controller.allow_forgery_protection = false + config.log_level = :info RUBY end @@ -162,6 +163,8 @@ module TestHelpers app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4" app.config.session_store :cookie_store, key: "_myapp_session" app.config.active_support.deprecation = :log + app.config.active_support.test_order = :random + app.config.log_level = :info yield app if block_given? app.initialize! |