diff options
Diffstat (limited to 'activerecord')
39 files changed, 147 insertions, 109 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 620d256d16..d5c141630e 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,6 +1,25 @@ -* `time` columns can now affected by `time_zone_aware_attributes`. If you have +* Introduce the `:if_exists` option for `drop_table`. + + Example: + + drop_table(:posts, if_exists: true) + + That would execute: + + DROP TABLE IF EXISTS posts + + If the table doesn't exist, `if_exists: false` (the default) raises an + exception whereas `if_exists: true` does nothing. + + *Cody Cutrer*, *Stefan Kanev*, *Ryuta Kamizono* + +* Don't run SQL if attribute value is not changed for update_attribute method. + + *Prathamesh Sonpatki* + +* `time` columns can now get affected by `time_zone_aware_attributes`. If you have set `config.time_zone` to a value other than `'UTC'`, they will be treated - as in that time zone by default in Rails 5.0. If this is not the desired + as in that time zone by default in Rails 5.1. If this is not the desired behavior, you can set ActiveRecord::Base.time_zone_aware_types = [:datetime] diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index ce7f575150..bce9c5e1e3 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -108,7 +108,7 @@ module ActiveRecord end def save_changed_attribute(attr, old_value) - if attribute_changed?(attr) + if attribute_changed_by_setter?(attr) clear_attribute_changes(attr) unless _field_changed?(attr, old_value) else set_attribute_was(attr, old_value) if _field_changed?(attr, old_value) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 0f44c332ae..f905669a24 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -380,7 +380,7 @@ module ActiveRecord # it can be helpful to provide these in a migration's +change+ method so it can be reverted. # In that case, +options+ and the block will be used by create_table. def drop_table(table_name, options = {}) - execute "DROP TABLE #{quote_table_name(table_name)}" + execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}" end # Adds a new column to the named table. diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index e9a3c26c32..b61b717a61 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -502,7 +502,7 @@ module ActiveRecord end def drop_table(table_name, options = {}) - execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}" + execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}" end def rename_index(table_name, old_name, new_name) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index a90adcf4aa..afd7a17c03 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -112,7 +112,7 @@ module ActiveRecord end def drop_table(table_name, options = {}) - execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}" + execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}" end # Returns true if schema exists. diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 6306a25745..714d36e7c0 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -246,7 +246,7 @@ module ActiveRecord name = name.to_s verify_readonly_attribute(name) send("#{name}=", value) - save(validate: false) + save(validate: false) if changed? end # Updates the attributes of the model from the passed-in hash and saves the diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index dd78814c6a..9c4db8a05e 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -33,7 +33,6 @@ module ActiveRecord # This method is a hot spot, so for now, use Hash[] to dup the hash. # https://bugs.ruby-lang.org/issues/7166 @values = Hash[@values] - @values[:bind] = @values[:bind].dup if @values.key? :bind reset end diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 567efce8ae..2860a30f99 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -28,6 +28,27 @@ module ActiveRecord expand_from_hash(attributes) end + def create_binds(attributes) + result = attributes.dup + binds = [] + + attributes.each do |column_name, value| + case value + when String, Integer, ActiveRecord::StatementCache::Substitute + result[column_name] = Arel::Nodes::BindParam.new + binds.push([table.column(column_name), value]) + when Hash + attrs, bvs = associated_predicate_builder(column_name).create_binds(value) + result[column_name] = attrs + binds += bvs + when Relation + binds += value.arel.bind_values + value.bind_values + end + end + + [result, binds] + end + def expand(column, value) # Find the foreign key when using queries such as: # Post.where(author: author) @@ -80,8 +101,7 @@ module ActiveRecord attributes.flat_map do |key, value| if value.is_a?(Hash) - builder = self.class.new(table.associated_table(key)) - builder.expand_from_hash(value) + associated_predicate_builder(key).expand_from_hash(value) else expand(key, value) end @@ -90,6 +110,10 @@ module ActiveRecord private + def associated_predicate_builder(association_name) + self.class.new(table.associated_table(association_name)) + end + def convert_dot_notation_to_hash(attributes) dot_notation = attributes.keys.select { |s| s.include?(".") } diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index d6e6cb4d05..c34e4bfb9b 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -909,7 +909,7 @@ module ActiveRecord end end - bind_values.reject! { |col,_| col.name == target_value } + self.bind_values = bind_values.reject { |col,_| col.name == target_value } end def custom_join_ast(table, joins) @@ -945,11 +945,10 @@ module ActiveRecord when Hash opts = predicate_builder.resolve_column_aliases(opts) - tmp_opts, bind_values = create_binds(opts) + tmp_opts, bind_values = predicate_builder.create_binds(opts) self.bind_values += bind_values attributes = @klass.send(:expand_hash_conditions_for_aggregates, tmp_opts) - add_relations_to_bind_values(attributes) predicate_builder.build_from_hash(attributes) else @@ -957,40 +956,6 @@ module ActiveRecord end end - def create_binds(opts) - bindable, non_binds = opts.partition do |column, value| - case value - when String, Integer, ActiveRecord::StatementCache::Substitute - @klass.columns_hash.include? column.to_s - else - false - end - end - - association_binds, non_binds = non_binds.partition do |column, value| - value.is_a?(Hash) && association_for_table(column) - end - - new_opts = {} - binds = [] - - bindable.each do |(column,value)| - binds.push [@klass.columns_hash[column.to_s], value] - new_opts[column] = connection.substitute_at(column) - end - - association_binds.each do |(column, value)| - association_relation = association_for_table(column).klass.send(:relation) - association_new_opts, association_bind = association_relation.send(:create_binds, value) - new_opts[column] = association_new_opts - binds += association_bind - end - - non_binds.each { |column,value| new_opts[column] = value } - - [new_opts, binds] - end - def association_for_table(table_name) table_name = table_name.to_s @klass._reflect_on_association(table_name) || @@ -1153,17 +1118,5 @@ module ActiveRecord raise ArgumentError, "The method .#{method_name}() must contain arguments." end end - - def add_relations_to_bind_values(attributes) - if attributes.is_a?(Hash) - attributes.each_value do |value| - if value.is_a?(ActiveRecord::Relation) - self.bind_values += value.arel.bind_values + value.bind_values - else - add_relations_to_bind_values(value) - end - end - end - end end end diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb index 11e33e8dfe..31a40adb67 100644 --- a/activerecord/lib/active_record/table_metadata.rb +++ b/activerecord/lib/active_record/table_metadata.rb @@ -22,6 +22,12 @@ module ActiveRecord arel_table[column_name] end + def column(column_name) + if klass + klass.columns_hash[column_name.to_s] + end + end + def associated_with?(association_name) klass && klass._reflect_on_association(association_name) end diff --git a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb index 9c49599d34..06b0cb5515 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb @@ -16,7 +16,7 @@ module ActiveRecord def test_initializes_schema_migrations_for_encoding_utf8mb4 smtn = ActiveRecord::Migrator.schema_migrations_table_name - connection.drop_table(smtn) if connection.table_exists?(smtn) + connection.drop_table smtn, if_exists: true config = connection.instance_variable_get(:@config) original_encoding = config[:encoding] diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb index 77055f5b7a..331f33455e 100644 --- a/activerecord/test/cases/adapters/postgresql/array_test.rb +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -112,8 +112,8 @@ class PostgresqlArrayTest < ActiveRecord::TestCase def test_schema_dump_with_shorthand output = dump_table_schema "pg_arrays" - assert_match %r[t.string\s+"tags",\s+array: true], output - assert_match %r[t.integer\s+"ratings",\s+array: true], output + assert_match %r[t\.string\s+"tags",\s+array: true], output + assert_match %r[t\.integer\s+"ratings",\s+array: true], output end def test_select_with_strings diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb index 5a8083f7a7..cfbe842948 100644 --- a/activerecord/test/cases/adapters/postgresql/citext_test.rb +++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb @@ -72,7 +72,7 @@ if ActiveRecord::Base.connection.supports_extensions? def test_schema_dump_with_shorthand output = dump_table_schema("citexts") - assert_match %r[t.citext "cival"], output + assert_match %r[t\.citext "cival"], output end end end diff --git a/activerecord/test/cases/adapters/postgresql/full_text_test.rb b/activerecord/test/cases/adapters/postgresql/full_text_test.rb index a370a5adc6..e7e5d8e32a 100644 --- a/activerecord/test/cases/adapters/postgresql/full_text_test.rb +++ b/activerecord/test/cases/adapters/postgresql/full_text_test.rb @@ -39,6 +39,6 @@ class PostgresqlFullTextTest < ActiveRecord::TestCase def test_schema_dump_with_shorthand output = dump_table_schema("tsvectors") - assert_match %r{t.tsvector "text_vector"}, output + assert_match %r{t\.tsvector "text_vector"}, output end end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index a0aa10630c..2ca123409a 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -317,7 +317,7 @@ if ActiveRecord::Base.connection.supports_extensions? def test_schema_dump_with_shorthand output = dump_table_schema("hstores") - assert_match %r[t.hstore "tags",\s+default: {}], output + assert_match %r[t\.hstore "tags",\s+default: {}], output end private diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index 7be7e00463..5f6cda1986 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -66,7 +66,7 @@ module PostgresqlJSONSharedTestCases def test_schema_dumping output = dump_table_schema("json_data_type") - assert_match(/t.#{column_type.to_s}\s+"payload",\s+default: {}/, output) + assert_match(/t\.#{column_type.to_s}\s+"payload",\s+default: {}/, output) end def test_cast_value_on_write diff --git a/activerecord/test/cases/adapters/postgresql/ltree_test.rb b/activerecord/test/cases/adapters/postgresql/ltree_test.rb index 771a825840..c5371348ea 100644 --- a/activerecord/test/cases/adapters/postgresql/ltree_test.rb +++ b/activerecord/test/cases/adapters/postgresql/ltree_test.rb @@ -48,6 +48,6 @@ class PostgresqlLtreeTest < ActiveRecord::TestCase def test_schema_dump_with_shorthand output = dump_table_schema("ltrees") - assert_match %r[t.ltree "path"], output + assert_match %r[t\.ltree "path"], output end end diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb index f3a24eee85..78afd49b0b 100644 --- a/activerecord/test/cases/adapters/postgresql/money_test.rb +++ b/activerecord/test/cases/adapters/postgresql/money_test.rb @@ -56,7 +56,7 @@ class PostgresqlMoneyTest < ActiveRecord::TestCase def test_schema_dumping output = dump_table_schema("postgresql_moneys") assert_match %r{t\.money\s+"wealth",\s+scale: 2$}, output - assert_match %r{t\.money\s+"depth",\s+scale: 2,\s+default: 150.55$}, output + assert_match %r{t\.money\s+"depth",\s+scale: 2,\s+default: 150\.55$}, output end def test_create_and_update_money diff --git a/activerecord/test/cases/adapters/postgresql/network_test.rb b/activerecord/test/cases/adapters/postgresql/network_test.rb index daa590f369..741876d3ca 100644 --- a/activerecord/test/cases/adapters/postgresql/network_test.rb +++ b/activerecord/test/cases/adapters/postgresql/network_test.rb @@ -85,8 +85,8 @@ class PostgresqlNetworkTest < ActiveRecord::TestCase def test_schema_dump_with_shorthand output = dump_table_schema("postgresql_network_addresses") - assert_match %r{t.inet\s+"inet_address",\s+default: "192.168.1.1"}, output - assert_match %r{t.cidr\s+"cidr_address",\s+default: "192.168.1.0/24"}, output - assert_match %r{t.macaddr\s+"mac_address",\s+default: "ff:ff:ff:ff:ff:ff"}, output + assert_match %r{t\.inet\s+"inet_address",\s+default: "192\.168\.1\.1"}, output + assert_match %r{t\.cidr\s+"cidr_address",\s+default: "192\.168\.1\.0/24"}, output + assert_match %r{t\.macaddr\s+"mac_address",\s+default: "ff:ff:ff:ff:ff:ff"}, output end end diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index e99f1e2867..642b63357f 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -454,7 +454,7 @@ class SchemaForeignKeyTest < ActiveRecord::TestCase end @connection.add_foreign_key "wagons", "my_schema.trains", column: "train_id" output = dump_table_schema "wagons" - assert_match %r{\s+add_foreign_key "wagons", "my_schema.trains", column: "train_id"$}, output + assert_match %r{\s+add_foreign_key "wagons", "my_schema\.trains", column: "train_id"$}, output ensure @connection.execute "DROP TABLE IF EXISTS wagons" @connection.execute "DROP TABLE IF EXISTS my_schema.trains" diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index 7d2fae69d5..d328f17a3f 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -114,7 +114,7 @@ class PostgresqlUUIDTest < ActiveRecord::TestCase def test_schema_dump_with_shorthand output = dump_table_schema "uuid_data_type" - assert_match %r{t.uuid "guid"}, output + assert_match %r{t\.uuid "guid"}, output end def test_uniqueness_validation_ignores_uuid diff --git a/activerecord/test/cases/adapters/postgresql/xml_test.rb b/activerecord/test/cases/adapters/postgresql/xml_test.rb index 5aba118518..ac8464a65d 100644 --- a/activerecord/test/cases/adapters/postgresql/xml_test.rb +++ b/activerecord/test/cases/adapters/postgresql/xml_test.rb @@ -50,6 +50,6 @@ class PostgresqlXMLTest < ActiveRecord::TestCase def test_schema_dump_with_shorthand output = dump_table_schema("xml_data_type") - assert_match %r{t.xml "payload"}, output + assert_match %r{t\.xml "payload"}, output end end diff --git a/activerecord/test/cases/associations/required_test.rb b/activerecord/test/cases/associations/required_test.rb index 321fb6c8dd..a6123ac432 100644 --- a/activerecord/test/cases/associations/required_test.rb +++ b/activerecord/test/cases/associations/required_test.rb @@ -18,8 +18,8 @@ class RequiredAssociationsTest < ActiveRecord::TestCase end teardown do - @connection.drop_table 'parents' if @connection.table_exists? 'parents' - @connection.drop_table 'children' if @connection.table_exists? 'children' + @connection.drop_table 'parents', if_exists: true + @connection.drop_table 'children', if_exists: true end test "belongs_to associations are not required by default" do diff --git a/activerecord/test/cases/attribute_decorators_test.rb b/activerecord/test/cases/attribute_decorators_test.rb index 53bd58e22e..9ad02ffae8 100644 --- a/activerecord/test/cases/attribute_decorators_test.rb +++ b/activerecord/test/cases/attribute_decorators_test.rb @@ -28,7 +28,7 @@ module ActiveRecord teardown do return unless @connection - @connection.drop_table 'attribute_decorators_model' if @connection.table_exists? 'attribute_decorators_model' + @connection.drop_table 'attribute_decorators_model', if_exists: true Model.attribute_type_decorations.clear Model.reset_column_information end diff --git a/activerecord/test/cases/date_time_test.rb b/activerecord/test/cases/date_time_test.rb index 330232cee2..4cbff564aa 100644 --- a/activerecord/test/cases/date_time_test.rb +++ b/activerecord/test/cases/date_time_test.rb @@ -55,7 +55,7 @@ class DateTimeTest < ActiveRecord::TestCase now = DateTime.now with_timezone_config default: :local do task = Task.new starting: now - assert now, task.starting + assert_equal now, task.starting end end end diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb index e9bc583bf4..b9db0d0123 100644 --- a/activerecord/test/cases/defaults_test.rb +++ b/activerecord/test/cases/defaults_test.rb @@ -40,7 +40,7 @@ class DefaultNumbersTest < ActiveRecord::TestCase end teardown do - @connection.drop_table "default_numbers" if @connection.table_exists? 'default_numbers' + @connection.drop_table :default_numbers, if_exists: true end def test_default_positive_integer diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index ae4a8aab2c..192ba6f7cd 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -721,6 +721,14 @@ class DirtyTest < ActiveRecord::TestCase assert record.save end + test "mutating and then assigning doesn't remove the change" do + pirate = Pirate.create!(catchphrase: "arrrr") + pirate.catchphrase << " matey!" + pirate.catchphrase = "arrrr matey!" + + assert pirate.catchphrase_changed?(from: "arrrr", to: "arrrr matey!") + end + private def with_partial_writes(klass, on = true) old = klass.partial_writes? diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb index b3129a8984..a4bff0cbb9 100644 --- a/activerecord/test/cases/migration/change_schema_test.rb +++ b/activerecord/test/cases/migration/change_schema_test.rb @@ -403,6 +403,17 @@ module ActiveRecord end end + def test_drop_table_if_exists + connection.create_table(:testings) + assert connection.table_exists?(:testings) + connection.drop_table(:testings, if_exists: true) + assert_not connection.table_exists?(:testings) + end + + def test_drop_table_if_exists_nothing_raised + assert_nothing_raised { connection.drop_table(:nonexistent, if_exists: true) } + end + private def testing_table_with_only_foo_attribute connection.create_table :testings, :id => false do |t| @@ -426,7 +437,7 @@ module ActiveRecord teardown do [:wagons, :trains].each do |table| - @connection.drop_table(table) if @connection.table_exists?(table) + @connection.drop_table table, if_exists: true end end diff --git a/activerecord/test/cases/migration/column_positioning_test.rb b/activerecord/test/cases/migration/column_positioning_test.rb index 62186e13a5..4637970ce0 100644 --- a/activerecord/test/cases/migration/column_positioning_test.rb +++ b/activerecord/test/cases/migration/column_positioning_test.rb @@ -3,7 +3,7 @@ require 'cases/helper' module ActiveRecord class Migration class ColumnPositioningTest < ActiveRecord::TestCase - attr_reader :connection, :table_name + attr_reader :connection alias :conn :connection def setup diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb index f8b1bf8c9d..78d9dd90a3 100644 --- a/activerecord/test/cases/migration/foreign_key_test.rb +++ b/activerecord/test/cases/migration/foreign_key_test.rb @@ -29,8 +29,8 @@ module ActiveRecord teardown do if defined?(@connection) - @connection.drop_table "astronauts" if @connection.table_exists? 'astronauts' - @connection.drop_table "rockets" if @connection.table_exists? 'rockets' + @connection.drop_table "astronauts", if_exists: true + @connection.drop_table "rockets", if_exists: true end end diff --git a/activerecord/test/cases/migration/rename_table_test.rb b/activerecord/test/cases/migration/rename_table_test.rb index a018bac43d..3eef308428 100644 --- a/activerecord/test/cases/migration/rename_table_test.rb +++ b/activerecord/test/cases/migration/rename_table_test.rb @@ -86,8 +86,8 @@ module ActiveRecord assert connection.table_exists? :felines ensure disable_extension!('uuid-ossp', connection) - connection.drop_table :cats if connection.table_exists? :cats - connection.drop_table :felines if connection.table_exists? :felines + connection.drop_table :cats, if_exists: true + connection.drop_table :felines, if_exists: true end end end diff --git a/activerecord/test/cases/migration/table_and_index_test.rb b/activerecord/test/cases/migration/table_and_index_test.rb index 8fd770abd1..24cba84a09 100644 --- a/activerecord/test/cases/migration/table_and_index_test.rb +++ b/activerecord/test/cases/migration/table_and_index_test.rb @@ -6,11 +6,11 @@ module ActiveRecord def test_add_schema_info_respects_prefix_and_suffix conn = ActiveRecord::Base.connection - conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name) + conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name, if_exists: true) # Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters ActiveRecord::Base.table_name_prefix = 'p_' ActiveRecord::Base.table_name_suffix = '_s' - conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name) + conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name, if_exists: true) conn.initialize_schema_migrations_table diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 7c2d3e81d6..a5d7cc2dff 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -90,7 +90,7 @@ class MigrationTest < ActiveRecord::TestCase end def test_migration_detection_without_schema_migration_table - ActiveRecord::Base.connection.drop_table('schema_migrations') if ActiveRecord::Base.connection.table_exists?('schema_migrations') + ActiveRecord::Base.connection.drop_table 'schema_migrations', if_exists: true migrations_path = MIGRATIONS_ROOT + "/valid" old_path = ActiveRecord::Migrator.migrations_paths diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index d6816041bc..2803ad2de0 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -356,6 +356,16 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal("David", topic_reloaded.author_name) end + def test_update_attribute_does_not_run_sql_if_attribute_is_not_changed + klass = Class.new(Topic) do + def self.name; 'Topic'; end + end + topic = klass.create(title: 'Another New Topic') + assert_queries(0) do + topic.update_attribute(:title, 'Another New Topic') + end + end + def test_delete topic = Topic.find(1) assert_equal topic, topic.delete, 'topic.delete did not return self' diff --git a/activerecord/test/cases/relation/predicate_builder_test.rb b/activerecord/test/cases/relation/predicate_builder_test.rb index 0cc081fced..8f62014622 100644 --- a/activerecord/test/cases/relation/predicate_builder_test.rb +++ b/activerecord/test/cases/relation/predicate_builder_test.rb @@ -8,7 +8,7 @@ module ActiveRecord Arel::Nodes::InfixOperation.new('~', column, Arel.sql(value.source)) end) - assert_match %r{["`]topics["`].["`]title["`] ~ rails}i, Topic.where(title: /rails/).to_sql + assert_match %r{["`]topics["`]\.["`]title["`] ~ rails}i, Topic.where(title: /rails/).to_sql ensure Topic.reset_column_information end diff --git a/activerecord/test/cases/relation/where_chain_test.rb b/activerecord/test/cases/relation/where_chain_test.rb index 619055f1e7..0f9019bb1b 100644 --- a/activerecord/test/cases/relation/where_chain_test.rb +++ b/activerecord/test/cases/relation/where_chain_test.rb @@ -42,7 +42,7 @@ module ActiveRecord end def test_association_not_eq - expected = Comment.arel_table[@name].not_eq('hello') + expected = Comment.arel_table[@name].not_eq(Arel::Nodes::BindParam.new) relation = Post.joins(:comments).where.not(comments: {title: 'hello'}) assert_equal(expected.to_sql, relation.where_values.first.to_sql) end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index b0573579da..537937decd 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -28,6 +28,14 @@ module ActiveRecord } end + def test_where_copies_bind_params_in_the_right_order + author = authors(:david) + posts = author.posts.where.not(id: 1) + joined = Post.where(id: posts, title: posts.first.title) + + assert_equal joined, [posts.first] + end + def test_where_copies_arel_bind_params chef = Chef.create! CakeDesigner.create!(chef: chef) diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index b52c66356c..c8ea702488 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -204,25 +204,25 @@ class SchemaDumperTest < ActiveRecord::TestCase if current_adapter?(:MysqlAdapter, :Mysql2Adapter) def test_schema_dump_should_add_default_value_for_mysql_text_field output = standard_dump - assert_match %r{t.text\s+"body",\s+limit: 65535,\s+null: false$}, output + assert_match %r{t\.text\s+"body",\s+limit: 65535,\s+null: false$}, output end def test_schema_dump_includes_length_for_mysql_binary_fields output = standard_dump - assert_match %r{t.binary\s+"var_binary",\s+limit: 255$}, output - assert_match %r{t.binary\s+"var_binary_large",\s+limit: 4095$}, output + assert_match %r{t\.binary\s+"var_binary",\s+limit: 255$}, output + assert_match %r{t\.binary\s+"var_binary_large",\s+limit: 4095$}, output end def test_schema_dump_includes_length_for_mysql_blob_and_text_fields output = standard_dump - assert_match %r{t.binary\s+"tiny_blob",\s+limit: 255$}, output - assert_match %r{t.binary\s+"normal_blob",\s+limit: 65535$}, output - assert_match %r{t.binary\s+"medium_blob",\s+limit: 16777215$}, output - assert_match %r{t.binary\s+"long_blob",\s+limit: 4294967295$}, output - assert_match %r{t.text\s+"tiny_text",\s+limit: 255$}, output - assert_match %r{t.text\s+"normal_text",\s+limit: 65535$}, output - assert_match %r{t.text\s+"medium_text",\s+limit: 16777215$}, output - assert_match %r{t.text\s+"long_text",\s+limit: 4294967295$}, output + assert_match %r{t\.binary\s+"tiny_blob",\s+limit: 255$}, output + assert_match %r{t\.binary\s+"normal_blob",\s+limit: 65535$}, output + assert_match %r{t\.binary\s+"medium_blob",\s+limit: 16777215$}, output + assert_match %r{t\.binary\s+"long_blob",\s+limit: 4294967295$}, output + assert_match %r{t\.text\s+"tiny_text",\s+limit: 255$}, output + assert_match %r{t\.text\s+"normal_text",\s+limit: 65535$}, output + assert_match %r{t\.text\s+"medium_text",\s+limit: 16777215$}, output + assert_match %r{t\.text\s+"long_text",\s+limit: 4294967295$}, output end def test_schema_dumps_index_type @@ -235,19 +235,19 @@ class SchemaDumperTest < ActiveRecord::TestCase if mysql_56? def test_schema_dump_includes_datetime_precision output = standard_dump - assert_match %r{t.datetime\s+"written_on",\s+precision: 6$}, output + assert_match %r{t\.datetime\s+"written_on",\s+precision: 6$}, output end end def test_schema_dump_includes_decimal_options output = dump_all_table_schema([/^[^n]/]) - assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: 2.78}, output + assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: 2\.78}, output end if current_adapter?(:PostgreSQLAdapter) def test_schema_dump_includes_bigint_default output = standard_dump - assert_match %r{t.integer\s+"bigint_default",\s+limit: 8,\s+default: 0}, output + assert_match %r{t\.integer\s+"bigint_default",\s+limit: 8,\s+default: 0}, output end if ActiveRecord::Base.connection.supports_extensions? @@ -271,11 +271,11 @@ class SchemaDumperTest < ActiveRecord::TestCase output = standard_dump # Oracle supports precision up to 38 and it identifies decimals with scale 0 as integers if current_adapter?(:OracleAdapter) - assert_match %r{t.integer\s+"atoms_in_universe",\s+precision: 38}, output + assert_match %r{t\.integer\s+"atoms_in_universe",\s+precision: 38}, output elsif current_adapter?(:FbAdapter) - assert_match %r{t.integer\s+"atoms_in_universe",\s+precision: 18}, output + assert_match %r{t\.integer\s+"atoms_in_universe",\s+precision: 18}, output else - assert_match %r{t.decimal\s+"atoms_in_universe",\s+precision: 55}, output + assert_match %r{t\.decimal\s+"atoms_in_universe",\s+precision: 55}, output end end @@ -284,7 +284,7 @@ class SchemaDumperTest < ActiveRecord::TestCase match = output.match(%r{create_table "goofy_string_id"(.*)do.*\n(.*)\n}) assert_not_nil(match, "goofy_string_id table not found") assert_match %r(id: false), match[1], "no table id not preserved" - assert_match %r{t.string\s+"id",.*?null: false$}, match[2], "non-primary key id column not preserved" + assert_match %r{t\.string\s+"id",.*?null: false$}, match[2], "non-primary key id column not preserved" end def test_schema_dump_keeps_id_false_when_id_is_false_and_unique_not_null_column_added diff --git a/activerecord/test/cases/xml_serialization_test.rb b/activerecord/test/cases/xml_serialization_test.rb index c34e7d5a30..b30b50f597 100644 --- a/activerecord/test/cases/xml_serialization_test.rb +++ b/activerecord/test/cases/xml_serialization_test.rb @@ -19,7 +19,7 @@ class XmlSerializationTest < ActiveRecord::TestCase def test_should_serialize_default_root_with_namespace @xml = Contact.new.to_xml :namespace=>"http://xml.rubyonrails.org/contact" - assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, @xml + assert_match %r{^<contact xmlns="http://xml\.rubyonrails\.org/contact">}, @xml assert_match %r{</contact>$}, @xml end |