diff options
12 files changed, 90 insertions, 46 deletions
diff --git a/actionmailer/lib/action_mailer/preview.rb b/actionmailer/lib/action_mailer/preview.rb index fde0e86f5b..33a9faa7e7 100644 --- a/actionmailer/lib/action_mailer/preview.rb +++ b/actionmailer/lib/action_mailer/preview.rb @@ -20,7 +20,7 @@ module ActionMailer interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) } end - # Register am Interceptor which will be called before mail is previewed. + # Register an Interceptor which will be called before mail is previewed. # Either a class or a string can be passed in as the Interceptor. If a # string is passed in it will be <tt>constantize</tt>d. def register_preview_interceptor(interceptor) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index d8bb31a3a7..458b9d77c2 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,16 @@ +* Perform necessary deeper encoding when hstore is inside an array. + + Fixes #11135. + + *Josh Goodall*, *Genadi Samokovarov* + +* Properly detect if a connection is still active before using it + in multi-threaded environments. + + Fixes #12867. + + *Kevin Casey*, *Matthew Draper*, *William (B.J.) Snow Orvis* + * When inverting add_index use the index name if present instead of the columns. @@ -520,22 +533,6 @@ *Damien Mathieu* -* Improve the default select when `from` is used. - - Previously, if you did something like Topic.from(:temp_topics), it - would generate SQL like: - - SELECT topics.* FROM temp_topics; - - Which is will cause an error since there's not a topics table to select - from. - - Now the default if you use from is just `*`: - - SELECT * FROM temp_topics; - - *Cody Cutrer* - * Fix `PostgreSQL` insert to properly extract table name from multiline string SQL. Previously, executing an insert SQL in `PostgreSQL` with a command like this: @@ -750,7 +747,7 @@ * Raise `ActiveRecord::RecordNotDestroyed` when a replaced child marked with `dependent: destroy` fails to be destroyed. - Fixex #12812. + Fixes #12812. *Brian Thomas Storti* diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb index 35ce881302..3a3b500b1f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb @@ -35,11 +35,11 @@ module ActiveRecord end end - def hstore_to_string(object) + def hstore_to_string(object, array_member = false) if Hash === object - object.map { |k,v| - "#{escape_hstore(k)}=>#{escape_hstore(v)}" - }.join ',' + string = object.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(',') + string = escape_hstore(string) if array_member + string else object end @@ -49,10 +49,10 @@ module ActiveRecord if string.nil? nil elsif String === string - Hash[string.scan(HstorePair).map { |k,v| + Hash[string.scan(HstorePair).map { |k, v| v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') - [k,v] + [k, v] }] else string diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index c1f978a081..210172cf32 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -121,7 +121,7 @@ module ActiveRecord end when Hash case column.sql_type - when 'hstore' then PostgreSQLColumn.hstore_to_string(value) + when 'hstore' then PostgreSQLColumn.hstore_to_string(value, array_member) when 'json' then PostgreSQLColumn.json_to_string(value) else super(value, column) end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 077f09b67d..5d38f0dce8 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -240,7 +240,7 @@ module ActiveRecord def select!(*fields) # :nodoc: fields.flatten! fields.map! do |field| - klass.attribute_alias?(field) ? klass.attribute_alias(field).to_sym : field + klass.attribute_alias?(field) ? klass.attribute_alias(field) : field end self.select_values += fields self @@ -995,8 +995,6 @@ module ActiveRecord columns_hash.key?(field.to_s) ? arel_table[field] : field end arel.project(*expanded_select) - elsif from_value - arel.project(Arel.star) else arel.project(@klass.arel_table[Arel.star]) end @@ -1052,11 +1050,11 @@ module ActiveRecord order_args.map! do |arg| case arg when Symbol - arg = klass.attribute_alias(arg).to_sym if klass.attribute_alias?(arg) + arg = klass.attribute_alias(arg) if klass.attribute_alias?(arg) table[arg].asc when Hash arg.map { |field, dir| - field = klass.attribute_alias(field).to_sym if klass.attribute_alias?(field) + field = klass.attribute_alias(field) if klass.attribute_alias?(field) table[field].send(dir) } else diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index d8782f5eaa..f2502430de 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -24,6 +24,7 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase @connection.transaction do @connection.create_table('hstores') do |t| t.hstore 'tags', :default => '' + t.hstore 'payload', array: true t.hstore 'settings' end end @@ -182,6 +183,30 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase assert_equal({'1' => '2'}, x.tags) end + def test_array_cycle + assert_array_cycle([{"AA" => "BB", "CC" => "DD"}, {"AA" => nil}]) + end + + def test_array_strings_with_quotes + assert_array_cycle([{'this has' => 'some "s that need to be escaped"'}]) + end + + def test_array_strings_with_commas + assert_array_cycle([{'this,has' => 'many,values'}]) + end + + def test_array_strings_with_array_delimiters + assert_array_cycle(['{' => '}']) + end + + def test_array_strings_with_null_strings + assert_array_cycle([{'NULL' => 'NULL'}]) + end + + def test_contains_nils + assert_array_cycle([{'NULL' => nil}]) + end + def test_select_multikey @connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')" x = Hstore.first @@ -237,6 +262,20 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase private + def assert_array_cycle(array) + # test creation + x = Hstore.create!(payload: array) + x.reload + assert_equal(array, x.payload) + + # test updating + x = Hstore.create!(payload: []) + x.payload = array + x.save! + x.reload + assert_equal(array, x.payload) + end + def assert_cycle(hash) # test creation x = Hstore.create!(:tags => hash) diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb index 02834edf7b..73cb739b2b 100644 --- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb @@ -33,9 +33,8 @@ module ActiveRecord end end - def test_connect_with_url - skip "can't establish new connection when using memory db" if in_memory_db? - begin + unless in_memory_db? + def test_connect_with_url original_connection = ActiveRecord::Base.remove_connection tf = Tempfile.open 'whatever' url = "sqlite3://#{tf.path}" @@ -46,11 +45,8 @@ module ActiveRecord tf.unlink ActiveRecord::Base.establish_connection(original_connection) end - end - def test_connect_memory_with_url - skip "can't establish new connection when using memory db" if in_memory_db? - begin + def test_connect_memory_with_url original_connection = ActiveRecord::Base.remove_connection url = "sqlite3:///:memory:" ActiveRecord::Base.establish_connection(url) diff --git a/activerecord/test/cases/associations/eager_singularization_test.rb b/activerecord/test/cases/associations/eager_singularization_test.rb index 669569a774..b12bc355e8 100644 --- a/activerecord/test/cases/associations/eager_singularization_test.rb +++ b/activerecord/test/cases/associations/eager_singularization_test.rb @@ -1,6 +1,7 @@ require "cases/helper" +if ActiveRecord::Base.connection.supports_migrations? class EagerSingularizationTest < ActiveRecord::TestCase class Virus < ActiveRecord::Base belongs_to :octopus @@ -50,8 +51,6 @@ class EagerSingularizationTest < ActiveRecord::TestCase end def setup - skip 'Does not support migrations' unless connection.supports_migrations? - connection.create_table :viri do |t| t.column :octopus_id, :integer t.column :species, :string @@ -146,3 +145,4 @@ class EagerSingularizationTest < ActiveRecord::TestCase end end end +end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index e390d37871..8718110c36 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -151,11 +151,14 @@ class RelationTest < ActiveRecord::TestCase assert_equal relation.to_a, Comment.select('a.*').from(relation, :a).to_a end - def test_finding_with_subquery_without_select - relation = Topic.where(:approved => true) - assert_equal relation.to_a, Topic.from(relation).to_a + def test_finding_with_subquery_without_select_does_not_change_the_select + relation = Topic.where(approved: true) + assert_raises(ActiveRecord::StatementInvalid) do + Topic.from(relation).to_a + end end + def test_finding_with_conditions assert_equal ["David"], Author.where(:name => 'David').map(&:name) assert_equal ['Mary'], Author.where(["name = ?", 'Mary']).map(&:name) diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index 9ae3fbb0b5..fa2e57ff92 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -1018,7 +1018,8 @@ The X-Sendfile header is a directive to the web server to ignore the response from the application, and instead serve a specified file from disk. This option is off by default, but can be enabled if your server supports it. When enabled, this passes responsibility for serving the file to the web server, which is -faster. +faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file) +on how to use this feature. Apache and nginx support this option, which can be enabled in `config/environments/production.rb`: @@ -1033,6 +1034,10 @@ option, take care to paste this configuration option only into `production.rb` and any other environments you define with production behavior (not `application.rb`). +TIP: For further details have a look at the docs of your production web server: +- [Apache](https://tn123.org/mod_xsendfile/) +- [Nginx](http://wiki.nginx.org/XSendfile) + Assets Cache Store ------------------ diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 5264f82b4b..53d2a9b55b 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -1119,7 +1119,11 @@ The `method: :patch` 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. -TIP: By default forms built with the _form_for_ helper are sent via `POST`. +The first parameter of the `form_tag` 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. More details +can be found in [form_for documentation](http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for). Next we need to create the `update` action in `app/controllers/articles_controller.rb`: @@ -1390,7 +1394,9 @@ class CreateComments < ActiveRecord::Migration create_table :comments do |t| t.string :commenter t.text :body - t.references :article, index: true + + # this line adds an integer column called `article_id`. + t.references :article, index: true t.timestamps end diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md index 3c04204c29..a8695ec034 100644 --- a/guides/source/working_with_javascript_in_rails.md +++ b/guides/source/working_with_javascript_in_rails.md @@ -180,7 +180,7 @@ bind to the `ajax:success` event. On failure, use `ajax:error`. Check it out: $(document).ready -> $("#new_post").on("ajax:success", (e, data, status, xhr) -> $("#new_post").append xhr.responseText - ).bind "ajax:error", (e, xhr, status, error) -> + ).on "ajax:error", (e, xhr, status, error) -> $("#new_post").append "<p>ERROR</p>" ``` |