aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock22
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/request_encoder.rb2
-rw-r--r--actionpack/test/controller/integration_test.rb2
-rw-r--r--activerecord/lib/active_record/relation.rb8
-rw-r--r--activerecord/test/cases/persistence_test.rb22
-rw-r--r--activerecord/test/cases/test_fixtures_test.rb2
-rw-r--r--activesupport/test/concern_test.rb2
-rw-r--r--guides/source/getting_started.md7
-rw-r--r--guides/source/testing.md7
-rw-r--r--railties/CHANGELOG.md9
-rw-r--r--railties/lib/rails/generators/app_base.rb55
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/setup.tt5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/update.tt5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/package.json5
-rw-r--r--railties/test/generators/api_app_generator_test.rb1
-rw-r--r--railties/test/generators/app_generator_test.rb26
21 files changed, 172 insertions, 30 deletions
diff --git a/Gemfile b/Gemfile
index 0f6a64db6f..e30858a124 100644
--- a/Gemfile
+++ b/Gemfile
@@ -19,7 +19,6 @@ gem "jquery-rails"
gem "coffee-rails"
gem "sass-rails"
gem "turbolinks", "~> 5"
-gem "rails-ujs", github: "rails/rails-ujs"
# require: false so bcrypt is loaded only when has_secure_password is used.
# This is to avoid Active Model (and by extension the entire framework)
@@ -39,6 +38,8 @@ gem "rb-inotify", github: "matthewd/rb-inotify", branch: "close-handling", requi
# Explicitly avoid 1.x that doesn't support Ruby 2.4+
gem "json", ">= 2.0.0"
+gem "rubocop", require: false
+
group :doc do
gem "sdoc", "1.0.0.beta2"
gem "redcarpet", "~> 3.2.3", platforms: :ruby
diff --git a/Gemfile.lock b/Gemfile.lock
index bc88ca95bc..eb14330c2b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -39,13 +39,6 @@ GIT
websocket
GIT
- remote: https://github.com/rails/rails-ujs.git
- revision: 767692f53dec79d42928029a55fdfcced35681e8
- specs:
- rails-ujs (0.0.1)
- railties (>= 3.1)
-
-GIT
remote: https://github.com/resque/resque.git
revision: 20d885065ac19e7f7d7a982f4ed1296083db0300
specs:
@@ -129,6 +122,7 @@ GEM
public_suffix (~> 2.0, >= 2.0.2)
amq-protocol (2.0.1)
arel (7.1.2)
+ ast (2.3.0)
backburner (1.3.1)
beaneater (~> 1.0)
concurrent-ruby (~> 1.0.1)
@@ -254,9 +248,12 @@ GEM
mini_portile2 (~> 2.1.0)
nokogiri (1.6.8.1-x86-mingw32)
mini_portile2 (~> 2.1.0)
+ parser (2.3.2.0)
+ ast (~> 2.2)
pg (0.19.0)
pg (0.19.0-x64-mingw32)
pg (0.19.0-x86-mingw32)
+ powerpack (0.1.1)
psych (2.1.1)
public_suffix (2.0.4)
puma (3.6.0)
@@ -280,6 +277,7 @@ GEM
nokogiri (~> 1.6.0)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
+ rainbow (2.1.0)
rake (11.3.0)
rb-fsevent (0.9.7)
rdoc (5.0.0.beta2)
@@ -292,6 +290,13 @@ GEM
redis (~> 3.3)
resque (~> 1.26)
rufus-scheduler (~> 3.2)
+ rubocop (0.45.0)
+ parser (>= 2.3.1.1, < 3.0)
+ powerpack (~> 0.1)
+ rainbow (>= 1.99.1, < 3.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (~> 1.0, >= 1.0.1)
+ ruby-progressbar (1.8.1)
ruby_dep (1.4.0)
rubyzip (1.2.0)
rufus-scheduler (3.2.2)
@@ -355,6 +360,7 @@ GEM
tzinfo (>= 1.0.0)
uglifier (3.0.2)
execjs (>= 0.3.0, < 3)
+ unicode-display_width (1.1.1)
useragent (0.16.8)
vegas (0.1.11)
rack (>= 1.0.0)
@@ -406,13 +412,13 @@ DEPENDENCIES
racc (>= 1.4.6)
rack-cache (~> 1.2)
rails!
- rails-ujs!
rake (>= 11.1)
rb-inotify!
redcarpet (~> 3.2.3)
redis
resque!
resque-scheduler
+ rubocop
sass!
sass-rails
sdoc (= 1.0.0.beta2)
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index b74c5d3e83..1ab6158c90 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -577,7 +577,8 @@ module ActionDispatch
# end
# end
#
- # The +as+ option sets the format to JSON, sets the content type to
+ # The +as+ option passes an "application/json" Accept header (thereby setting
+ # the request format to JSON unless overridden), sets the content type to
# "application/json" and encodes the parameters as JSON.
#
# Calling +parsed_body+ on the response parses the response body based on the
diff --git a/actionpack/lib/action_dispatch/testing/request_encoder.rb b/actionpack/lib/action_dispatch/testing/request_encoder.rb
index 734fc8cb54..8c27e9ecb7 100644
--- a/actionpack/lib/action_dispatch/testing/request_encoder.rb
+++ b/actionpack/lib/action_dispatch/testing/request_encoder.rb
@@ -11,7 +11,7 @@ module ActionDispatch
attr_reader :response_parser
- def initialize(mime_name, param_encoder, response_parser = nil)
+ def initialize(mime_name, param_encoder, response_parser)
@mime = Mime[mime_name]
unless @mime
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index d8be5d32e1..d3aa81a0f7 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -145,7 +145,7 @@ class IntegrationTestTest < ActiveSupport::TestCase
name.to_s == "foo" ? "pass" : super
end
end
- @test.class.superclass.__send__(:include, mixin)
+ @test.class.superclass.include(mixin)
begin
assert_equal "pass", @test.foo
ensure
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 6f602e4a23..4e941cf2df 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -373,7 +373,7 @@ module ActiveRecord
stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
stmt.table(table)
- if joins_values.any?
+ if has_join_values?
@klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
else
stmt.key = arel_attribute(primary_key)
@@ -522,7 +522,7 @@ module ActiveRecord
stmt = Arel::DeleteManager.new
stmt.from(table)
- if joins_values.any?
+ if has_join_values?
@klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
else
stmt.wheres = arel.constraints
@@ -680,6 +680,10 @@ module ActiveRecord
private
+ def has_join_values?
+ joins_values.any? || left_outer_joins_values.any?
+ end
+
def exec_queries(&block)
@records = eager_loading? ? find_with_associations.freeze : @klass.find_by_sql(arel, bound_attributes, &block).freeze
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index f667e9b055..3f1da82cb4 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -90,6 +90,14 @@ class PersistenceTest < ActiveRecord::TestCase
assert_equal count, Pet.joins(:toys).where(where_args).delete_all
end
+ def test_delete_all_with_left_joins
+ where_args = { toys: { name: "Bone" } }
+ count = Pet.left_joins(:toys).where(where_args).count
+
+ assert_equal count, 1
+ assert_equal count, Pet.left_joins(:toys).where(where_args).delete_all
+ end
+
def test_delete_all_with_joins_and_where_part_is_not_hash
where_args = ["toys.name = ?", "Bone"]
count = Pet.joins(:toys).where(where_args).count
@@ -453,6 +461,20 @@ class PersistenceTest < ActiveRecord::TestCase
assert_nil Topic.find(2).last_read
end
+ def test_update_all_with_joins
+ where_args = { toys: { name: "Bone" } }
+ count = Pet.left_joins(:toys).where(where_args).count
+
+ assert_equal count, Pet.joins(:toys).where(where_args).update_all(name: "Bob")
+ end
+
+ def test_update_all_with_left_joins
+ where_args = { toys: { name: "Bone" } }
+ count = Pet.left_joins(:toys).where(where_args).count
+
+ assert_equal count, Pet.left_joins(:toys).where(where_args).update_all(name: "Bob")
+ end
+
def test_update_all_with_non_standard_table_name
assert_equal 1, WarehouseThing.where(id: 1).update_all(["value = ?", 0])
assert_equal 0, WarehouseThing.find(1).value
diff --git a/activerecord/test/cases/test_fixtures_test.rb b/activerecord/test/cases/test_fixtures_test.rb
index 14a5faa85e..7090202a89 100644
--- a/activerecord/test/cases/test_fixtures_test.rb
+++ b/activerecord/test/cases/test_fixtures_test.rb
@@ -3,7 +3,7 @@ require "cases/helper"
class TestFixturesTest < ActiveRecord::TestCase
setup do
@klass = Class.new
- @klass.send(:include, ActiveRecord::TestFixtures)
+ @klass.include(ActiveRecord::TestFixtures)
end
def test_deprecated_use_transactional_fixtures=
diff --git a/activesupport/test/concern_test.rb b/activesupport/test/concern_test.rb
index 95507c815d..7a5a5414a7 100644
--- a/activesupport/test/concern_test.rb
+++ b/activesupport/test/concern_test.rb
@@ -76,7 +76,7 @@ class ConcernTest < ActiveSupport::TestCase
end
def test_class_methods_are_extended_only_on_expected_objects
- ::Object.__send__(:include, Qux)
+ ::Object.include(Qux)
Object.extend(Qux::ClassMethods)
# module needs to be created after Qux is included in Object or bug won't
# be triggered
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index c04d42d743..6ec5106bb3 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1157,7 +1157,7 @@ it look as follows:
```html+erb
<h1>Edit article</h1>
-<%= form_for :article, url: article_path(@article), method: :patch do |f| %>
+<%= form_for(@article) do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
@@ -1195,14 +1195,15 @@ it look as follows:
This time we point the form to the `update` action, which is not defined yet
but will be very soon.
-The `method: :patch` option tells Rails that we want this form to be submitted
+Passing the article object to the method, will automagically create url for submitting the edited article form.
+This option tells Rails that we want this form to be submitted
via the `PATCH` HTTP method which is the HTTP method you're expected to use to
**update** resources according to the REST protocol.
The first parameter of `form_for` can be an object, say, `@article` which would
cause the helper to fill in the form with the fields of the object. Passing in a
symbol (`:article`) with the same name as the instance variable (`@article`)
-also automagically leads to the same behavior. This is what is happening here.
+also automagically leads to the same behavior.
More details can be found in [form_for documentation]
(http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for).
diff --git a/guides/source/testing.md b/guides/source/testing.md
index bc1f78fb2a..29a9537141 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -800,6 +800,13 @@ end
Now you can try running all the tests and they should pass.
+NOTE: If you followed the steps in the Basic Authentication section, you'll need to add the following to the `setup` block to get all the tests passing:
+
+```ruby
+request.headers['Authorization'] = ActionController::HttpAuthentication::Basic.
+ encode_credentials('dhh', 'secret')
+```
+
### Available Request Types for Functional Tests
If you're familiar with the HTTP protocol, you'll know that `get` is a type of request. There are 6 request types supported in Rails functional tests:
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 5e5583734a..819d760433 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,5 +1,10 @@
-* Removed jquery-rails from default stack, instead rails-ujs is
- included as default UJS adapter.
+* Add Yarn support in new apps using --yarn option. This add a package.json
+ and the settings needed to get npm modules integrated in new apps.
+
+ *Liceth Ovalles*, *Guillermo Iguaran*
+
+* Removed jquery-rails from default stack, instead rails-ujs that is shipped
+ with Action View is included as default UJS adapter.
*Guillermo Iguaran*
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 2951d6c83d..99fc5d9525 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -33,6 +33,9 @@ module Rails
class_option :javascript, type: :string, aliases: "-j",
desc: "Preconfigure for selected JavaScript library"
+ class_option :yarn, type: :boolean, default: false,
+ desc: "Preconfigure for assets management with Yarn"
+
class_option :skip_gemfile, type: :boolean, default: false,
desc: "Don't create a Gemfile"
@@ -333,9 +336,6 @@ module Rails
"Use #{options[:javascript]} as the JavaScript library")
end
- gems << GemfileEntry.github("rails-ujs", "rails/rails-ujs", nil,
- "Unobstrusive JavaScript adapter for Rails")
-
unless options[:skip_turbolinks]
gems << GemfileEntry.version("turbolinks", "~> 5",
"Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks")
@@ -414,6 +414,55 @@ module Rails
bundle_command("install") if bundle_install?
end
+ def run_yarn
+ if package_json_exist?
+ if yarn_path
+ say_status :run, "yarn install"
+ yarn_command("install")
+ else
+ say_status :warning, "yarn option passed but Yarn executable was not detected in the system.", :yellow
+ say_status :warning, "Download Yarn at https://yarnpkg.com/en/docs/install", :yellow
+ end
+ end
+ end
+
+ def package_json_exist?
+ File.exist?("package.json")
+ end
+
+ def yarn_path
+ commands = ["yarn"]
+
+ if RbConfig::CONFIG["host_os"] =~ /mswin|cygwin/
+ ENV["PATHEXT"].split(File::PATH_SEPARATOR).each do |ext|
+ commands << commands[0] + ext
+ end
+ end
+
+ yarn_path = commands.find do |cmd|
+ paths = ENV["PATH"].split(File::PATH_SEPARATOR)
+
+ path = paths.find do |p|
+ full_path = File.expand_path(cmd, p)
+ File.executable?(full_path) && File.file?(full_path)
+ end
+
+ path && File.expand_path(cmd, path)
+ end
+
+ yarn_path
+ end
+
+ def yarn_command(command)
+ full_command = "#{yarn_path} #{command}"
+
+ if options[:quiet]
+ system(full_command, out: File::NULL)
+ else
+ system(full_command)
+ end
+ end
+
def generate_spring_binstubs
if bundle_install? && spring_install?
bundle_command("exec spring binstub --all")
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index d6ffa2d89d..03fd298fbc 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -53,6 +53,10 @@ module Rails
template "gitignore", ".gitignore"
end
+ def packagejson
+ template "package.json"
+ end
+
def app
directory "app"
@@ -205,6 +209,7 @@ module Rails
build(:readme)
build(:rakefile)
build(:configru)
+ build(:packagejson) if options[:yarn]
build(:gitignore) unless options[:skip_git]
build(:gemfile) unless options[:skip_gemfile]
end
@@ -355,7 +360,7 @@ module Rails
end
public_task :apply_rails_template, :run_bundle
- public_task :generate_spring_binstubs
+ public_task :run_yarn, :generate_spring_binstubs
def run_after_bundle_callbacks
@after_bundle_callbacks.each(&:call)
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/setup.tt b/railties/lib/rails/generators/rails/app/templates/bin/setup.tt
index 8635e97b76..c82a922eef 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/setup.tt
+++ b/railties/lib/rails/generators/rails/app/templates/bin/setup.tt
@@ -16,8 +16,11 @@ chdir APP_ROOT do
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
-<% unless options.skip_active_record -%>
+<% if options[:yarn] %>
+ system! 'yarn'
+<% end %>
+<% unless options.skip_active_record -%>
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml'
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/update.tt b/railties/lib/rails/generators/rails/app/templates/bin/update.tt
index d385b363c6..0d8ca2f902 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/update.tt
+++ b/railties/lib/rails/generators/rails/app/templates/bin/update.tt
@@ -16,8 +16,11 @@ chdir APP_ROOT do
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
-<% unless options.skip_active_record -%>
+<% if options[:yarn] %>
+ system! 'yarn'
+<% end %>
+<% unless options.skip_active_record -%>
puts "\n== Updating database =="
system! 'bin/rails db:migrate'
<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt
index 2318cf59ff..1ba182e562 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt
@@ -5,6 +5,10 @@ Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
+<%- if options[:yarn] -%>
+# Add Yarn node_modules folder to the asset load path.
+Rails.application.config.assets.paths << Rails.root.join('node_modules')
+<%- end -%>
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index 0e66cc4237..bdcbe8d629 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
@@ -21,5 +21,10 @@
!/tmp/.keep
<% end -%>
+<% if options[:yarn] -%>
+# Ignore node modules.
+/node_modules/*
+
+<% end -%>
# Ignore Byebug command history file.
.byebug_history
diff --git a/railties/lib/rails/generators/rails/app/templates/package.json b/railties/lib/rails/generators/rails/app/templates/package.json
new file mode 100644
index 0000000000..46db57dcbe
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "<%= app_name %>",
+ "private": true,
+ "dependencies": {}
+}
diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb
index cefad48f52..7069a07bbe 100644
--- a/railties/test/generators/api_app_generator_test.rb
+++ b/railties/test/generators/api_app_generator_test.rb
@@ -35,7 +35,6 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
assert_file "Gemfile" do |content|
assert_no_match(/gem 'coffee-rails'/, content)
- assert_no_match(/gem 'rails-ujs'/, content)
assert_no_match(/gem 'sass-rails'/, content)
assert_no_match(/gem 'web-console'/, content)
assert_match(/# gem 'jbuilder'/, content)
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 2d01da7f46..0f73c43e0c 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -452,7 +452,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "app/assets/javascripts/application.js" do |contents|
assert_match %r{^//= require rails-ujs}, contents
end
- assert_gem "rails-ujs"
end
def test_inclusion_of_javascript_libraries_if_required
@@ -477,7 +476,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "Gemfile" do |content|
assert_no_match(/coffee-rails/, content)
assert_no_match(/uglifier/, content)
- assert_no_match(/rails-ujs/, content)
end
assert_file "config/environments/production.rb" do |content|
@@ -494,6 +492,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generator_if_yarn_option_is_given
+ run_generator([destination_root, "--yarn"])
+ assert_file "package.json", /dependencies/
+ assert_file "config/initializers/assets.rb", /node_modules/
+ end
+
def test_inclusion_of_jbuilder
run_generator
assert_gem "jbuilder"
@@ -614,6 +618,10 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_generates_with_bundler
end
+ def test_generation_runs_yarn_install_with_yarn_option
+ assert_generates_with_yarn yarn: true
+ end
+
def test_dev_option
assert_generates_with_bundler dev: true
rails_path = File.expand_path("../../..", Rails.root)
@@ -839,4 +847,18 @@ class AppGeneratorTest < Rails::Generators::TestCase
quietly { generator.invoke_all }
end
end
+
+ def assert_generates_with_yarn(options = {})
+ generator([destination_root], options)
+
+ command_check = -> command do
+ @install_called ||= 0
+ @install_called += 1
+ assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
+ end
+
+ generator.stub :yarn_command, command_check do
+ quietly { generator.invoke_all }
+ end
+ end
end