Skip to content

Commit 4942ea2

Browse files
committed
Merge pull request #634 from rikettsie/master
#623: solve matching of binary-encoded strings with MySql (via rake rule or initializer setting)
2 parents 16908df + 14063a7 commit 4942ea2

File tree

7 files changed

+71
-35
lines changed

7 files changed

+71
-35
lines changed

CHANGELOG.md

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ Each change should fall into categories that would affect whether the release is
44

55
As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch. And _misc_ is either minor or patch, the difference being kind of fuzzy for the purposes of history. Adding tests would be patch level.
66

7-
### Master [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.4...master)
7+
### Master [fixes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.4...master)
88

9-
* Breaking Changes
10-
* Features
119
* Fixes
12-
* Performance
13-
* Misc
10+
* [@rikettsie Fixed collation for MySql via rake rule or config parameter](https://github.com/mbleigh/acts-as-taggable-on/pull/634)
1411

1512
### [3.4.4 / 2015-02-11](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.4.3...v3.4.4)
1613

Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ group :local_development do
88
gem 'appraisal'
99
gem 'rake'
1010
gem 'byebug' , platform: :mri_21
11-
end
11+
end

README.md

+25-8
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,22 @@ Review the generated migrations then migrate :
5757
rake db:migrate
5858
```
5959

60-
MySql users should also run the following rake task to get special characters
61-
work correctly for tag names, see [issue #623](https://github.com/mbleigh/acts-as-taggable-on/issues/623):
60+
#### For MySql users
61+
You can circumvent at any time the problem of special characters [issue 623](https://github.com/mbleigh/acts-as-taggable-on/issues/623) by setting in an initializer file:
6262

63-
```shell
64-
rake acts_as_taggable_on_engine:tag_names:collate
63+
```ruby
64+
ActsAsTaggableOn.force_binary_collation = true
6565
```
6666

67-
or, alternatively, execute the following command in the MySql console:
67+
Or by running this rake task:
6868

6969
```shell
70-
USE my_wonderful_app_db;
71-
ALTER TABLE tags MODIFY name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;
70+
rake acts_as_taggable_on_engine:tag_names:collate_bin
7271
```
7372

73+
See the Configuration section for more details, and a general note valid for older
74+
version of the gem.
75+
7476
#### Upgrading
7577

7678
see [UPGRADING](UPGRADING.md)
@@ -421,13 +423,28 @@ If you would like tags to be case-sensitive and not use LIKE queries for creatio
421423
ActsAsTaggableOn.strict_case_match = true
422424
```
423425

426+
If you would like to have an exact match covering special characters with MySql:
427+
428+
```ruby
429+
ActsAsTaggableOn.force_binary_collation = true
430+
```
431+
424432
If you want to change the default delimiter (it defaults to ','). You can also pass in an array of delimiters such as ([',', '|']):
425433

426434
```ruby
427435
ActsAsTaggableOn.delimiter = ','
428436
```
429437

430-
*NOTE: SQLite by default can't upcase or downcase multibyte characters, resulting in unwanted behavior. Load the SQLite ICU extension for proper handle of such characters. [See docs](http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt)*
438+
*NOTE 1: SQLite by default can't upcase or downcase multibyte characters, resulting in unwanted behavior. Load the SQLite ICU extension for proper handle of such characters. [See docs](http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt)*
439+
440+
*NOTE 2: the option `force_binary_collation` is strongest than `strict_case_match` and when
441+
set to true, the `strict_case_match` is ignored.
442+
To roughly apply the `force_binary_collation` behaviour with a version of the gem <= 3.4.4, execute the following commands in the MySql console:*
443+
444+
```shell
445+
USE my_wonderful_app_db;
446+
ALTER TABLE tags MODIFY name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;
447+
```
431448

432449
## Contributors
433450

db/migrate/5_change_collation_for_tag_names.rb

-15
This file was deleted.

lib/acts-as-taggable-on.rb

+31
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ def initialize
6969
@remove_unused_tags = false
7070
@tags_counter = true
7171
@default_parser = DefaultParser
72+
@force_binary_collation = false
73+
end
74+
75+
def strict_case_match=(force_cs)
76+
if @force_binary_collation == false
77+
@strict_case_match = force_cs
78+
end
7279
end
7380

7481
def delimiter=(string)
@@ -79,6 +86,30 @@ def delimiter=(string)
7986
WARNING
8087
@delimiter = string
8188
end
89+
90+
def force_binary_collation=(force_bin)
91+
if Utils.using_mysql?
92+
if force_bin == true
93+
Configuration.apply_binary_collation(true)
94+
@force_binary_collation = true
95+
@strict_case_match = true
96+
else
97+
Configuration.apply_binary_collation(false)
98+
@force_binary_collation = false
99+
end
100+
end
101+
end
102+
103+
def self.apply_binary_collation(bincoll)
104+
if Utils.using_mysql?
105+
coll = 'utf8_general_ci'
106+
if bincoll == true
107+
coll = 'utf8_bin'
108+
end
109+
ActiveRecord::Migration.execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE #{coll};")
110+
end
111+
end
112+
82113
end
83114

84115
setup

lib/tasks/tags_collate_utf8.rake

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
# This rake task is to be run by MySql users only, and fixes the management of
2-
# binary-encoded strings for tag 'names'. Issues:
1+
# These rake tasks are to be run by MySql users only, they fix the management of
2+
# binary-encoded strings for tag 'names'. Issues:
33
# https://github.com/mbleigh/acts-as-taggable-on/issues/623
44

55
namespace :acts_as_taggable_on_engine do
66

77
namespace :tag_names do
88

99
desc "Forcing collate of tag names to utf8_bin"
10-
task :collate => [:environment] do |t, args|
11-
puts "Changing collate for column 'name' of table 'tags'"
12-
ActiveRecord::Migration.execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
10+
task :collate_bin => [:environment] do |t, args|
11+
ActsAsTaggableOn::Configuration.apply_binary_collation(true)
12+
end
13+
14+
desc "Forcing collate of tag names to utf8_general_ci"
15+
task :collate_ci => [:environment] do |t, args|
16+
ActsAsTaggableOn::Configuration.apply_binary_collation(false)
1317
end
1418

1519
end

spec/acts_as_taggable_on/tag_spec.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'spec_helper'
33
require 'db/migrate/2_add_missing_unique_indices.rb'
44

5+
56
shared_examples_for 'without unique index' do
67
prepend_before(:all) { AddMissingUniqueIndices.down }
78
append_after(:all) do
@@ -309,7 +310,7 @@
309310
tag.save!
310311
end
311312
end
312-
313+
313314
it 'should find the most popular tags' do
314315
expect(ActsAsTaggableOn::Tag.most_used(3).first.name).to eq("golden_syrup")
315316
expect(ActsAsTaggableOn::Tag.most_used(3).length).to eq(3)
@@ -320,4 +321,5 @@
320321
expect(ActsAsTaggableOn::Tag.least_used(3).length).to eq(3)
321322
end
322323
end
324+
323325
end

0 commit comments

Comments
 (0)