From 07790d5832e1822ce7278f05db1fe8394b5eb780 Mon Sep 17 00:00:00 2001 From: Yves Senn <yves.senn@gmail.com> Date: Sun, 21 Jul 2013 12:43:42 +0200 Subject: test cases to describe the MySQL boolean behavior. --- .../test/cases/adapters/mysql2/boolean_test.rb | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 activerecord/test/cases/adapters/mysql2/boolean_test.rb diff --git a/activerecord/test/cases/adapters/mysql2/boolean_test.rb b/activerecord/test/cases/adapters/mysql2/boolean_test.rb new file mode 100644 index 0000000000..7d23ba28d2 --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/boolean_test.rb @@ -0,0 +1,91 @@ +require "cases/helper" + +class Mysql2BooleanTest < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + class BooleanType < ActiveRecord::Base + self.table_name = "mysql_booleans" + end + + setup do + @connection = ActiveRecord::Base.connection + @connection.create_table("mysql_booleans") do |t| + t.boolean "archived" + t.string "published", limit: 1 + end + BooleanType.reset_column_information + + @emulate_booleans = ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans + end + + teardown do + emulate_booleans @emulate_booleans + @connection.drop_table "mysql_booleans" + end + + test "column type with emulated booleans" do + emulate_booleans true + + assert_equal :boolean, boolean_column.type + assert_equal :string, string_column.type + end + + test "column type without emulated booleans" do + emulate_booleans false + + assert_equal :integer, boolean_column.type + assert_equal :string, string_column.type + end + + test "test type casting with emulated booleans" do + emulate_booleans true + + boolean = BooleanType.create!(archived: true, published: true) + attributes = boolean.reload.attributes_before_type_cast + + assert_equal 1, attributes["archived"] + assert_equal "1", attributes["published"] + + assert_equal "t", @connection.type_cast(true, boolean_column) + assert_equal "t", @connection.type_cast(true, string_column) + end + + test "test type casting without emulated booleans" do + emulate_booleans false + + boolean = BooleanType.create!(archived: true, published: true) + attributes = boolean.reload.attributes_before_type_cast + + assert_equal 1, attributes["archived"] + assert_equal "1", attributes["published"] + + assert_equal 1, @connection.type_cast(true, boolean_column) + assert_equal "t", @connection.type_cast(true, string_column) + end + + test "with booleans stored as 1 and 0" do + @connection.execute "INSERT INTO mysql_booleans(archived, published) VALUES(1, '1')" + boolean = BooleanType.first + assert_equal true, boolean.archived + assert_equal "1", boolean.published + end + + test "with booleans stored as t" do + @connection.execute "INSERT INTO mysql_booleans(published) VALUES('t')" + boolean = BooleanType.first + assert_equal "t", boolean.published + end + + def boolean_column + BooleanType.columns.find { |c| c.name == 'archived' } + end + + def string_column + BooleanType.columns.find { |c| c.name == 'published' } + end + + def emulate_booleans(value) + ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = value + BooleanType.reset_column_information + end +end -- cgit v1.2.3 From 07ae1e9b5557182f69e5ffbac54b334284abf36f Mon Sep 17 00:00:00 2001 From: Yves Senn <yves.senn@gmail.com> Date: Wed, 7 Aug 2013 17:59:27 +0200 Subject: Unifies mysql and mysql2 casting of booleans. --- activerecord/CHANGELOG.md | 7 +++++++ .../active_record/connection_adapters/abstract_mysql_adapter.rb | 6 ++++++ .../lib/active_record/connection_adapters/mysql_adapter.rb | 6 ------ activerecord/test/cases/adapters/mysql2/boolean_test.rb | 6 +++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 1e387769de..54c243951d 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* Unify boolean type casting for `MysqlAdapter` and `Mysql2Adapter`. + `type_cast` will return `1` for `true` and `0` for `false`. + + Fixes #11119. + + *Adam Williams*, *Yves Senn* + * Fix bug where has_one associaton record update result in crash, when replaced with itself. Fixes #12834. 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 138ab811dc..ee6ca4fb6f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -206,6 +206,12 @@ module ActiveRecord true end + def type_cast(value, column) + return super unless value == true || value == false + + value ? 1 : 0 + end + # MySQL 4 technically support transaction isolation, but it is affected by a bug # where the transaction level gets persisted for the whole session: # diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index a690404892..7b18b95c44 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -160,12 +160,6 @@ module ActiveRecord # QUOTING ================================================== - def type_cast(value, column) - return super unless value == true || value == false - - value ? 1 : 0 - end - def quote_string(string) #:nodoc: @connection.quote(string) end diff --git a/activerecord/test/cases/adapters/mysql2/boolean_test.rb b/activerecord/test/cases/adapters/mysql2/boolean_test.rb index 7d23ba28d2..267aa232d9 100644 --- a/activerecord/test/cases/adapters/mysql2/boolean_test.rb +++ b/activerecord/test/cases/adapters/mysql2/boolean_test.rb @@ -46,8 +46,8 @@ class Mysql2BooleanTest < ActiveRecord::TestCase assert_equal 1, attributes["archived"] assert_equal "1", attributes["published"] - assert_equal "t", @connection.type_cast(true, boolean_column) - assert_equal "t", @connection.type_cast(true, string_column) + assert_equal 1, @connection.type_cast(true, boolean_column) + assert_equal 1, @connection.type_cast(true, string_column) end test "test type casting without emulated booleans" do @@ -60,7 +60,7 @@ class Mysql2BooleanTest < ActiveRecord::TestCase assert_equal "1", attributes["published"] assert_equal 1, @connection.type_cast(true, boolean_column) - assert_equal "t", @connection.type_cast(true, string_column) + assert_equal 1, @connection.type_cast(true, string_column) end test "with booleans stored as 1 and 0" do -- cgit v1.2.3