Skip to content

Commit

Permalink
added rake rule and a config parameter to force binary collation (MySql)
Browse files Browse the repository at this point in the history
added migration and rake task

added rake rule and a config parameter to force binary collation (MySql)

Added test for binary string collation

included migration in test

added self to migration

moved binary collation migration to 'without unique index' context

moved binary collation parameter from migration to app configuration

(typo) removed import

(typo) missing Configuration class name

force_binary_collation change can be set by MySql users only

(typo) method name using_mysql?

when force_binary_collation is false, strict_case_match is not touch

force_binary_collation not used in context without_unique_index

updated README and simplified rake test

rake task calls Configuration function

updated README

Gemfile cleaned

cleaned READEME.md

Added test for binary string collation

(typo) removed import

(typo) method name using_mysql?

when force_binary_collation is false, strict_case_match is not touch

force_binary_collation not used in context without_unique_index

Gemfile cleaned
  • Loading branch information
rikettsie committed Mar 1, 2015
1 parent a13c7a2 commit 5140c6f
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch.
* Performance
* Misc

### [3.4.4 / 2015-02-26](v3.4.4...v3.4.5)
* Fixes
* [@rikettsie Fixed collation for MySql](https://github.com/mbleigh/acts-as-taggable-on/pull/634)

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

* Fixes
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ group :local_development do
gem 'appraisal'
gem 'rake'
gem 'byebug' , platform: :mri_21
end
end
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ Review the generated migrations then migrate :
rake db:migrate
```

#### For MySql users
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:

```ruby
ActsAsTaggableOn.force_binary_collation = true
```

Or by running this rake task:

```shell
rake acts_as_taggable_on_engine:tag_names:collate_bin
```

See the Configuration section for more details, and a general note valid for older
version of the gem.

#### Upgrading

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

If you would like to have an exact match covering special characters with MySql:

```ruby
ActsAsTaggableOn.force_binary_collation = true
```

If you want to change the default delimiter (it defaults to ','). You can also pass in an array of delimiters such as ([',', '|']):

```ruby
ActsAsTaggableOn.delimiter = ','
```

*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)*
*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)*

*NOTE 2: the option `force_binary_collation` is strongest than `strict_case_match` and when
set to true, the `strict_case_match` is ignored.
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:*

```shell
USE my_wonderful_app_db;
ALTER TABLE tags MODIFY name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;
```

## Contributors

Expand Down
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'rubygems'
require 'bundler/setup'

import "./lib/tasks/tags_collate_utf8.rake"

desc 'Default: run specs'
task default: :spec

Expand Down
31 changes: 31 additions & 0 deletions lib/acts-as-taggable-on.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ def initialize
@remove_unused_tags = false
@tags_counter = true
@default_parser = DefaultParser
@force_binary_collation = false
end

def strict_case_match=(force_cs)
if @force_binary_collation == false
@strict_case_match = force_cs
end
end

def delimiter=(string)
Expand All @@ -79,6 +86,30 @@ def delimiter=(string)
WARNING
@delimiter = string
end

def force_binary_collation=(force_bin)
if Utils.using_mysql?
if force_bin == true
Configuration.apply_binary_collation(true)
@force_binary_collation = true
@strict_case_match = true
else
Configuration.apply_binary_collation(false)
@force_binary_collation = false
end
end
end

def self.apply_binary_collation(bincoll)
if Utils.using_mysql?
coll = 'utf8_general_ci'
if bincoll == true
coll = 'utf8_bin'
end
ActiveRecord::Migration.execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE #{coll};")
end
end

end

setup
Expand Down
21 changes: 21 additions & 0 deletions lib/tasks/tags_collate_utf8.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# These rake tasks are to be run by MySql users only, they fix the management of
# binary-encoded strings for tag 'names'. Issues:
# https://github.com/mbleigh/acts-as-taggable-on/issues/623

namespace :acts_as_taggable_on_engine do

namespace :tag_names do

desc "Forcing collate of tag names to utf8_bin"
task :collate_bin => [:environment] do |t, args|
ActsAsTaggableOn::Configuration.apply_binary_collation(true)
end

desc "Forcing collate of tag names to utf8_general_ci"
task :collate_ci => [:environment] do |t, args|
ActsAsTaggableOn::Configuration.apply_binary_collation(false)
end

end

end
8 changes: 6 additions & 2 deletions spec/acts_as_taggable_on/tag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
require 'spec_helper'
require 'db/migrate/2_add_missing_unique_indices.rb'


shared_examples_for 'without unique index' do
prepend_before(:all) { AddMissingUniqueIndices.down }
prepend_before(:all) do
AddMissingUniqueIndices.down
end
append_after(:all) do
ActsAsTaggableOn::Tag.delete_all
AddMissingUniqueIndices.up
Expand Down Expand Up @@ -309,7 +312,7 @@
tag.save!
end
end

it 'should find the most popular tags' do
expect(ActsAsTaggableOn::Tag.most_used(3).first.name).to eq("golden_syrup")
expect(ActsAsTaggableOn::Tag.most_used(3).length).to eq(3)
Expand All @@ -320,4 +323,5 @@
expect(ActsAsTaggableOn::Tag.least_used(3).length).to eq(3)
end
end

end

0 comments on commit 5140c6f

Please sign in to comment.