diff options
-rw-r--r-- | actioncable/lib/rails/generators/channel/channel_generator.rb | 3 | ||||
-rw-r--r-- | actioncable/lib/rails/generators/channel/templates/assets/channel.js | 18 | ||||
-rw-r--r-- | actionview/CHANGELOG.md | 17 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/form_tag_helper.rb | 4 | ||||
-rw-r--r-- | actionview/test/template/form_tag_helper_test.rb | 10 | ||||
-rw-r--r-- | activerecord/CHANGELOG.md | 5 | ||||
-rw-r--r-- | activerecord/lib/active_record/internal_metadata.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/migration_test.rb | 17 | ||||
-rw-r--r-- | activesupport/lib/active_support/xml_mini/rexml.rb | 4 | ||||
-rw-r--r-- | activesupport/test/xml_mini/rexml_engine_test.rb | 26 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 2 | ||||
-rw-r--r-- | railties/CHANGELOG.md | 5 | ||||
-rw-r--r-- | railties/lib/rails/application.rb | 11 | ||||
-rw-r--r-- | railties/lib/rails/generators/named_base.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails/generators/rails/app/templates/config/secrets.yml | 8 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 25 | ||||
-rw-r--r-- | railties/test/generators/channel_generator_test.rb | 24 |
17 files changed, 158 insertions, 27 deletions
diff --git a/actioncable/lib/rails/generators/channel/channel_generator.rb b/actioncable/lib/rails/generators/channel/channel_generator.rb index 05fd21a954..47232252e3 100644 --- a/actioncable/lib/rails/generators/channel/channel_generator.rb +++ b/actioncable/lib/rails/generators/channel/channel_generator.rb @@ -16,7 +16,8 @@ module Rails if self.behavior == :invoke template "assets/cable.js", "app/assets/javascripts/cable.js" end - template "assets/channel.coffee", File.join('app/assets/javascripts/channels', class_path, "#{file_name}.coffee") + + js_template "assets/channel", File.join('app/assets/javascripts/channels', class_path, "#{file_name}") end generate_application_cable_files diff --git a/actioncable/lib/rails/generators/channel/templates/assets/channel.js b/actioncable/lib/rails/generators/channel/templates/assets/channel.js new file mode 100644 index 0000000000..ab0e68b11a --- /dev/null +++ b/actioncable/lib/rails/generators/channel/templates/assets/channel.js @@ -0,0 +1,18 @@ +App.<%= class_name.underscore %> = App.cable.subscriptions.create("<%= class_name %>Channel", { + connected: function() { + // Called when the subscription is ready for use on the server + }, + + disconnected: function() { + // Called when the subscription has been terminated by the server + }, + + received: function(data) { + // Called when there's incoming data on the websocket for this channel + }<%= actions.any? ? ",\n" : '' %> +<% actions.each do |action| -%> + <%=action %>: function() { + return this.perform('<%= action %>'); + }<%= action == actions[-1] ? '' : ",\n" %> +<% end -%> +}); diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 1d7ec77e70..0b40699c77 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,2 +1,19 @@ +* `select_tag`'s `include_blank` option for generation for blank option tag, now adds an empty space label, + when the value as well as content for option tag are empty, so that we confirm with html specification. + Ref: https://www.w3.org/TR/html5/forms.html#the-option-element. + + Generation of option before: + + ```html + <option value=""></option> + ``` + + Generation of option after: + + ```html + <option value="" label=" "></option> + ``` + + *Vipul A M * Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/actionview/CHANGELOG.md) for previous changes. diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index cfff0bef5d..82f2fd30c7 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -134,13 +134,15 @@ module ActionView if options.include?(:include_blank) include_blank = options.delete(:include_blank) + options_for_blank_options_tag = { value: '' } if include_blank == true include_blank = '' + options_for_blank_options_tag[:label] = ' ' end if include_blank - option_tags = content_tag("option".freeze, include_blank, value: '').safe_concat(option_tags) + option_tags = content_tag("option".freeze, include_blank, options_for_blank_options_tag).safe_concat(option_tags) end end diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb index 7b93c8dc29..5b0b708618 100644 --- a/actionview/test/template/form_tag_helper_test.rb +++ b/actionview/test/template/form_tag_helper_test.rb @@ -239,8 +239,8 @@ class FormTagHelperTest < ActionView::TestCase end def test_select_tag_with_include_blank - actual = select_tag "places", raw("<option>Home</option><option>Work</option><option>Pub</option>"), :include_blank => true - expected = %(<select id="places" name="places"><option value=""></option><option>Home</option><option>Work</option><option>Pub</option></select>) + actual = select_tag "places", raw("<option>Home</option><option>Work</option><option>Pub</option>"), include_blank: true + expected = %(<select id="places" name="places"><option value="" label=" "></option><option>Home</option><option>Work</option><option>Pub</option></select>) assert_dom_equal expected, actual end @@ -269,14 +269,14 @@ class FormTagHelperTest < ActionView::TestCase end def test_select_tag_with_prompt_and_include_blank - actual = select_tag "places", raw("<option>Home</option><option>Work</option><option>Pub</option>"), :prompt => "string", :include_blank => true - expected = %(<select name="places" id="places"><option value="">string</option><option value=""></option><option>Home</option><option>Work</option><option>Pub</option></select>) + actual = select_tag "places", raw("<option>Home</option><option>Work</option><option>Pub</option>"), prompt: "string", include_blank: true + expected = %(<select name="places" id="places"><option value="">string</option><option value="" label=" "></option><option>Home</option><option>Work</option><option>Pub</option></select>) assert_dom_equal expected, actual end def test_select_tag_with_nil_option_tags_and_include_blank actual = select_tag "places", nil, :include_blank => true - expected = %(<select id="places" name="places"><option value=""></option></select>) + expected = %(<select id="places" name="places"><option value="" label=" "></option></select>) assert_dom_equal expected, actual end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index f2700a2a8d..929f241b1b 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,8 @@ +* Fix logging edge case where if an attribute was of the binary type and + was provided as a Hash. + + *Jon Moss* + * Handle JSON deserialization correctly if the column default from database adapter returns `''` instead of `nil`. diff --git a/activerecord/lib/active_record/internal_metadata.rb b/activerecord/lib/active_record/internal_metadata.rb index 81db96bffd..17a5dc1d1b 100644 --- a/activerecord/lib/active_record/internal_metadata.rb +++ b/activerecord/lib/active_record/internal_metadata.rb @@ -19,7 +19,7 @@ module ActiveRecord end def []=(key, value) - first_or_initialize(key: key).update_attributes!(value: value) + find_or_initialize_by(key: key).update_attributes!(value: value) end def [](key) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 6ad028d31b..36b6662820 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -428,6 +428,23 @@ class MigrationTest < ActiveRecord::TestCase ENV["RACK_ENV"] = original_rack_env end + def test_internal_metadata_stores_environment_when_other_data_exists + ActiveRecord::InternalMetadata.delete_all + ActiveRecord::InternalMetadata[:foo] = 'bar' + + current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call + migrations_path = MIGRATIONS_ROOT + "/valid" + old_path = ActiveRecord::Migrator.migrations_paths + ActiveRecord::Migrator.migrations_paths = migrations_path + + current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call + ActiveRecord::Migrator.up(migrations_path) + assert_equal current_env, ActiveRecord::InternalMetadata[:environment] + assert_equal 'bar', ActiveRecord::InternalMetadata[:foo] + ensure + ActiveRecord::Migrator.migrations_paths = old_path + end + def test_rename_internal_metadata_table original_internal_metadata_table_name = ActiveRecord::Base.internal_metadata_table_name diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb index 924ed72345..95af5af2c0 100644 --- a/activesupport/lib/active_support/xml_mini/rexml.rb +++ b/activesupport/lib/active_support/xml_mini/rexml.rb @@ -20,11 +20,9 @@ module ActiveSupport data = StringIO.new(data || '') end - char = data.getc - if char.nil? + if data.eof? {} else - data.ungetc(char) silence_warnings { require 'rexml/document' } unless defined?(REXML::Document) doc = REXML::Document.new(data) diff --git a/activesupport/test/xml_mini/rexml_engine_test.rb b/activesupport/test/xml_mini/rexml_engine_test.rb index f0067ca656..6e9ce7ac11 100644 --- a/activesupport/test/xml_mini/rexml_engine_test.rb +++ b/activesupport/test/xml_mini/rexml_engine_test.rb @@ -22,14 +22,24 @@ class REXMLEngineTest < ActiveSupport::TestCase morning </root> eoxml - assert_equal_rexml(io) + hash = ActiveSupport::XmlMini.parse(io) + assert hash.has_key?('root') + assert hash['root'].has_key?('products') + assert_match "good", hash['root']['__content__'] + products = hash['root']['products'] + assert products.has_key?("__content__") + assert_match 'hello everyone', products['__content__'] + end + + def test_parse_from_empty_string + ActiveSupport::XmlMini.backend = 'REXML' + assert_equal({}, ActiveSupport::XmlMini.parse("")) + end + + def test_parse_from_frozen_string + ActiveSupport::XmlMini.backend = 'REXML' + xml_string = "<root></root>".freeze + assert_equal({"root" => {}}, ActiveSupport::XmlMini.parse(xml_string)) end - private - def assert_equal_rexml(xml) - parsed_xml = ActiveSupport::XmlMini.parse(xml) - xml.rewind if xml.respond_to?(:rewind) - hash = ActiveSupport::XmlMini.with_backend('REXML') { ActiveSupport::XmlMini.parse(xml) } - assert_equal(hash, parsed_xml) - end end diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 9a13e3bda7..928ab43b3b 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -1121,7 +1121,7 @@ If you want to select a set of records whether or not they have associated records you can use the `left_outer_joins` method. ```ruby -Author.left_outer_joins(:posts).uniq.select('authors.*, COUNT(posts.*) AS posts_count').group('authors.id') +Author.left_outer_joins(:posts).distinct.select('authors.*, COUNT(posts.*) AS posts_count').group('authors.id') ``` Which produces: diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 41fbf9044c..f3543d5dee 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,2 +1,7 @@ +## Rails 5.1.0.alpha ## + +* Added a shared section to config/secrets.yml that will be loaded for all environments. + + *DHH* Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/railties/CHANGELOG.md) for previous changes. diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index ed106c9918..c383de3e06 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -385,11 +385,16 @@ module Rails def secrets @secrets ||= begin secrets = ActiveSupport::OrderedOptions.new - yaml = config.paths["config/secrets"].first + yaml = config.paths["config/secrets"].first + if File.exist?(yaml) require "erb" - all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {} - env_secrets = all_secrets[Rails.env] + + all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {} + shared_secrets = all_secrets['shared'] + env_secrets = all_secrets[Rails.env] + + secrets.merge!(shared_secrets.symbolize_keys) if shared_secrets secrets.merge!(env_secrets.symbolize_keys) if env_secrets end diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index efbf51ddfb..ee076eb711 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -26,6 +26,10 @@ module Rails super end end + + def js_template(source, destination) + template(source + '.js', destination + '.js') + end end protected 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 cdea2fd060..8e995a5df1 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml @@ -10,6 +10,13 @@ # Make sure the secrets in this file are kept private # if you're sharing your code publicly. +# Shared secrets are available across all environments. + +shared: + api_key: 123 + +# Environmental secrets are only available for that specific environment. + development: secret_key_base: <%= app_secret %> @@ -18,5 +25,6 @@ test: # Do not keep production secrets in the repository, # instead read values from the environment. + production: secret_key_base: <%%= ENV["SECRET_KEY_BASE"] %> diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 9f3a9cd232..7ec25aeca1 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -555,6 +555,31 @@ module ApplicationTests assert_equal 'myamazonsecretaccesskey', app.secrets.aws_secret_access_key end + test "shared secrets saved in config/secrets.yml are loaded in app secrets" do + app_file 'config/secrets.yml', <<-YAML + shared: + api_key: 3b7cd727 + YAML + + app 'development' + + assert_equal '3b7cd727', app.secrets.api_key + end + + test "shared secrets will yield to environment specific secrets" do + app_file 'config/secrets.yml', <<-YAML + shared: + api_key: 3b7cd727 + + development: + api_key: abc12345 + YAML + + app 'development' + + assert_equal 'abc12345', app.secrets.api_key + end + test "blank config/secrets.yml does not crash the loading process" do app_file 'config/secrets.yml', <<-YAML YAML diff --git a/railties/test/generators/channel_generator_test.rb b/railties/test/generators/channel_generator_test.rb index d58b54ac24..e3edde681f 100644 --- a/railties/test/generators/channel_generator_test.rb +++ b/railties/test/generators/channel_generator_test.rb @@ -24,8 +24,24 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_match(/class ChatChannel < ApplicationCable::Channel/, channel) end - assert_file "app/assets/javascripts/channels/chat.coffee" do |channel| - assert_match(/App.cable.subscriptions.create "ChatChannel"/, channel) + assert_file "app/assets/javascripts/channels/chat.js" do |channel| + assert_match(/App.chat = App.cable.subscriptions.create\("ChatChannel/, channel) + end + end + + def test_channel_with_multiple_actions_is_created + run_generator ['chat', 'speak', 'mute'] + + assert_file "app/channels/chat_channel.rb" do |channel| + assert_match(/class ChatChannel < ApplicationCable::Channel/, channel) + assert_match(/def speak/, channel) + assert_match(/def mute/, channel) + end + + assert_file "app/assets/javascripts/channels/chat.js" do |channel| + assert_match(/App.chat = App.cable.subscriptions.create\("ChatChannel/, channel) + assert_match(/,\n\n speak/, channel) + assert_match(/,\n\n mute: function\(\) \{\n return this\.perform\('mute'\);\n \}\n\}\);/, channel) end end @@ -36,7 +52,7 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_match(/class ChatChannel < ApplicationCable::Channel/, channel) end - assert_no_file "app/assets/javascripts/channels/chat.coffee" + assert_no_file "app/assets/javascripts/channels/chat.js" end def test_cable_js_is_created_if_not_present_already @@ -52,7 +68,7 @@ class ChannelGeneratorTest < Rails::Generators::TestCase run_generator ['chat'], behavior: :revoke assert_no_file "app/channels/chat_channel.rb" - assert_no_file "app/assets/javascripts/channels/chat.coffee" + assert_no_file "app/assets/javascripts/channels/chat.js" assert_file "app/channels/application_cable/channel.rb" assert_file "app/channels/application_cable/connection.rb" |