deftest_validates_length_of_using_maximum_utf8with_kcode('UTF8') doTopic.validates_length_of:title, :maximum => 5
t =Topic.create("title" => "一二三四五", "content" => "whatever")
assert t.valid?
t.title="一二34五六"
assert !t.valid?
assert t.errors.on(:title)
assert_equal "is too long (maximum is 5 characters)", t.errors["title"]
endend
output
5) Failure:
test_validates_length_of_using_maximum_utf8(ValidationsTest)
[test/cases/validations_test.rb:1004:in`test_validates_length_of_using_maximum_utf8' test/cases/validations_test.rb:1442:in `with_kcode' test/cases/validations_test.rb:1000:in `test_validates_length_of_using_maximum_utf8'
./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:57:in`run']:<false> is not true.The error happens on this statement: assert t.valid?
ar_utf8.rb (ruby)
# this is a plain program that should duplicate the same error# but it doesn't -- everything works correctly.require'rubygems'require'activerecord'defwith_kcode(kcode)ifRUBY_VERSION<'1.9'
orig_kcode, $KCODE=$KCODE, kcode
beginyieldensure$KCODE= orig_kcode
endelseyieldendend@logger=Logger.new$stderrActiveRecord::Base.logger=@loggerActiveRecord::Base.colorize_logging=false# GRANT ALL PRIVILEGES ON my_activerecord_test.* to 'rails'@'localhost';
pool =ActiveRecord::Base.establish_connection(
:adapter => RUBY_PLATFORM=~/java/?'jdbcmysql' : 'mysql',
:username => 'rails',
:encoding => 'utf8',
:database => 'my_activerecord_test'
)
ActiveRecord::Schema.definedo
drop_table :postsif pool.connection.table_exists?(:posts)
create_table :postsdo |t|
t.string:subject
t.text:bodyendendclassPost < ActiveRecord::Base
validates_length_of :subject, :maximum => 5endwith_kcode('UTF8') do
p1 =Post.create(:subject => "一二三四五", :body => 'this is the body')
len1 = p1.subject.length
len2 = p1.subject.mb_chars.length
puts "length: #{len1}, #{len2}"
puts p1.valid?
puts p1.errors.on(:subject)
p2 =Post.find(:first)
p2.subject="一二34五六"
puts p2.valid?
puts p2.errors.on(:subject)
end
output
$ jruby ar_utf8.rbSQL (1.3ms) SETSQL_AUTO_IS_NULL=0--drop_table(:posts)
SQL (2.5ms) DROPTABLE`posts`->0.0037s
->0 rows
--create_table(:posts)
SQL (2.2ms) CREATETABLE`posts` (`id`int(11) DEFAULTNULL auto_increment PRIMARYKEY, `subject`varchar(255), `body` text) ENGINE=InnoDBCHARACTERSET utf8 COLLATE utf8_bin
->0.0072s
->0 rows
SQL (2.1ms) INSERTINTO`posts` (`subject`, `body`) VALUES('一二三四五', 'this is the body')
length: 15, 5truenilPostLoad (1.6ms) SELECT*FROM`posts`LIMIT1false
is too long (maximum is 5 characters)