Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Configuration option to allow for case-sensitive tags

When the strict_case_match flag is on, LIKE queries are not used to
find_or_create tags.
  • Loading branch information...
commit 954a818366d73fb8b4a47e62b897a5db4426d19a 1 parent 1884af8
Colin Shield authored
3  README.rdoc
@@ -228,6 +228,9 @@ If you want tags to be saved parametrized (you can redefine to_param as well):
ActsAsTaggableOn.force_parameterize = true
+If you would like tags to be case-sensitive and not use LIKE queries for creation:
+
+ ActsAsTaggableOn.strict_case_match = true
== Contributors
View
3  lib/acts-as-taggable-on.rb
@@ -16,6 +16,9 @@ module ActsAsTaggableOn
mattr_accessor :force_parameterize
@@force_parameterize = false
+ mattr_accessor :strict_case_match
+ @@strict_case_match = false
+
mattr_accessor :remove_unused_tags
self.remove_unused_tags = false
View
30 lib/acts_as_taggable_on/tag.rb
@@ -17,11 +17,19 @@ class Tag < ::ActiveRecord::Base
### SCOPES:
def self.named(name)
- where(["lower(name) = ?", name.downcase])
+ if ActsAsTaggableOn.strict_case_match
+ where(["name = ?", name])
+ else
+ where(["lower(name) = ?", name.downcase])
+ end
end
def self.named_any(list)
- where(list.map { |tag| sanitize_sql(["lower(name) = ?", tag.to_s.mb_chars.downcase]) }.join(" OR "))
+ if ActsAsTaggableOn.strict_case_match
+ where(list.map { |tag| sanitize_sql(["name = ?", tag.to_s.mb_chars]) }.join(" OR "))
+ else
+ where(list.map { |tag| sanitize_sql(["lower(name) = ?", tag.to_s.mb_chars.downcase]) }.join(" OR "))
+ end
end
def self.named_like(name)
@@ -35,7 +43,11 @@ def self.named_like_any(list)
### CLASS METHODS:
def self.find_or_create_with_like_by_name(name)
- named_like(name).first || create(:name => name)
+ if (ActsAsTaggableOn.strict_case_match)
+ self.find_or_create_all_with_like_by_name([name]).first
+ else
+ named_like(name).first || create(:name => name)
+ end
end
def self.find_or_create_all_with_like_by_name(*list)
@@ -45,9 +57,9 @@ def self.find_or_create_all_with_like_by_name(*list)
existing_tags = Tag.named_any(list).all
new_tag_names = list.reject do |name|
- name = comparable_name(name)
- existing_tags.any? { |tag| comparable_name(tag.name) == name }
- end
+ name = comparable_name(name)
+ existing_tags.any? { |tag| comparable_name(tag.name) == name }
+ end
created_tags = new_tag_names.map { |name| Tag.create(:name => name) }
existing_tags + created_tags
@@ -69,9 +81,9 @@ def count
class << self
private
- def comparable_name(str)
- str.mb_chars.downcase.to_s
- end
+ def comparable_name(str)
+ str.mb_chars.downcase.to_s
+ end
end
end
end
View
29 spec/acts_as_taggable_on/tag_spec.rb
@@ -150,4 +150,33 @@
end
+ describe "when using strict_case_match" do
+ before do
+ ActsAsTaggableOn.strict_case_match = true
+ end
+
+ after do
+ ActsAsTaggableOn.strict_case_match = false
+ end
+
+ it "should find by name" do
+ ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("awesome").should == @tag
+ end
+
+ it "should find by name case sensitively" do
+ tag_count = ActsAsTaggableOn::Tag.count
+ tag = ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("AWESOME")
+
+ ActsAsTaggableOn::Tag.count.should == tag_count + 1
+ tag.name.should == "AWESOME"
+ end
+
+ it "should have a named_scope named(something) that matches exactly" do
+ uppercase_tag = ActsAsTaggableOn::Tag.create(:name => "Cool")
+ @tag.name = "cool"
+ @tag.save!
+ ActsAsTaggableOn::Tag.named('cool').should include(@tag)
+ ActsAsTaggableOn::Tag.named('cool').should_not include(uppercase_tag)
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.