Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag names case sensitive #42

Closed
rmehner opened this issue Dec 15, 2017 · 1 comment
Closed

Tag names case sensitive #42

rmehner opened this issue Dec 15, 2017 · 1 comment

Comments

@rmehner
Copy link
Contributor

rmehner commented Dec 15, 2017

Hey there,

I have kind of a strange requirement, but it makes sense for the client: tag names have to be case sensitive and a tag named Ruby is not the same as ruby.

So here's what I did:

# config/initializers/gutentag.rb

# don't normalise tag names
Gutentag.normaliser = lambda { |name| name }

# overwrite validations, so uniqueness is not case insensitive as it is the default
class TagValidations
  def self.call(klass)
    new(klass).call
  end

  def initialize(klass)
    @klass = klass
  end

  def call
    klass.validates :name, presence: true, uniqueness: true, length: {maximum: 255}
  end

  private

  attr_reader :klass
end

Gutentag.tag_validations = TagValidations

Which works fine to a certain point, but there's a nuance in MySQL. Depending on the collation of the field (which often is utf8_general_ci, which is a default in many MySQL setups I have seen), the index might be case sensitive or not. If you set a unique index, like we do at

add_index :gutentag_tags, :name, :unique => true
MySQL will treat this index as case insensitive, meaning ruby and Ruby will be the same and therefore will throw an error.

To get it working, you have to change the collation to something that is case sensitive in MySQL (there's a whole bunch of docs about that here https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html).

In my case, I wrote this migration:

class ChangeCollationOfGutentagTags < ActiveRecord::Migration[5.2]
  def up
    execute "ALTER TABLE `gutentag_tags` CONVERT TO CHARACTER SET UTF8 COLLATE utf8_bin"
  end

  def down
    execute "ALTER TABLE `gutentag_tags` CONVERT TO CHARACTER SET UTF8 COLLATE utf8_general_ci"
  end
end

and it now works like a charm :)

I don't know if Gutentag can do anything about this (unlikely), but at least this is documented somewhere now :)

@pat
Copy link
Owner

pat commented Dec 16, 2017

Thanks - just noted this in the README, and released v1.1.0 👍

@pat pat closed this as completed Dec 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants