Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: mbleigh/acts-as-taggable-on
...
head fork: diaspora/acts-as-taggable-on
compare: master
Checking mergeability… Don’t worry, you can still create the pull request.
  • 4 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 11, 2011
Raphael Sofaer Stop using LIKE to do case insensitivity, instead just downcase every…
…thing on the way in. Tests now pass with a utf8_bin collation in MYSQL
5d61df5
Raphael Sofaer Regenerate gemspec to supress warning 498089b
Raphael Sofaer get rid of gem deps in gemspec 5f3a16a
Raphael Sofaer downcase query input in tagged_with method c3592fe
View
6 Gemfile
@@ -1,10 +1,10 @@
source :gemcutter
# Rails 3.0
-gem 'rails', '3.0.0.beta3'
-gem 'rspec', '2.0.0.beta.8'
+gem 'rails', '>= 3.0'
+gem 'rspec', '>= 2.0'
gem 'sqlite3-ruby', :require => 'sqlite3'
gem 'mysql'
gem 'pg'
gem 'jeweler'
-gem 'rcov'
+gem 'rcov'
View
111 acts-as-taggable-on.gemspec
@@ -1,6 +1,6 @@
# Generated by jeweler
# DO NOT EDIT THIS FILE DIRECTLY
-# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
+# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*-
Gem::Specification.new do |s|
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Michael Bleigh"]
- s.date = %q{2010-05-19}
+ s.date = %q{2011-03-11}
s.description = %q{With ActsAsTaggableOn, you could tag a single model on several contexts, such as skills, interests, and awards. It also provides other advanced functionality.}
s.email = %q{michael@intridea.com}
s.extra_rdoc_files = [
@@ -17,74 +17,73 @@ Gem::Specification.new do |s|
]
s.files = [
"CHANGELOG",
- "Gemfile",
- "MIT-LICENSE",
- "README.rdoc",
- "Rakefile",
- "VERSION",
- "generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb",
- "generators/acts_as_taggable_on_migration/templates/migration.rb",
- "lib/acts-as-taggable-on.rb",
- "lib/acts_as_taggable_on/acts_as_taggable_on.rb",
- "lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb",
- "lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb",
- "lib/acts_as_taggable_on/acts_as_taggable_on/core.rb",
- "lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb",
- "lib/acts_as_taggable_on/acts_as_taggable_on/related.rb",
- "lib/acts_as_taggable_on/acts_as_tagger.rb",
- "lib/acts_as_taggable_on/compatibility/Gemfile",
- "lib/acts_as_taggable_on/compatibility/active_record_backports.rb",
- "lib/acts_as_taggable_on/compatibility/postgresql.rb",
- "lib/acts_as_taggable_on/tag.rb",
- "lib/acts_as_taggable_on/tag_list.rb",
- "lib/acts_as_taggable_on/tagging.rb",
- "lib/acts_as_taggable_on/tags_helper.rb",
- "lib/generators/acts_as_taggable_on/migration/migration_generator.rb",
- "lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb",
- "rails/init.rb",
- "spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb",
- "spec/acts_as_taggable_on/acts_as_tagger_spec.rb",
- "spec/acts_as_taggable_on/tag_list_spec.rb",
- "spec/acts_as_taggable_on/tag_spec.rb",
- "spec/acts_as_taggable_on/taggable_spec.rb",
- "spec/acts_as_taggable_on/tagger_spec.rb",
- "spec/acts_as_taggable_on/tagging_spec.rb",
- "spec/acts_as_taggable_on/tags_helper_spec.rb",
- "spec/bm.rb",
- "spec/database.yml",
- "spec/database.yml.sample",
- "spec/models.rb",
- "spec/schema.rb",
- "spec/spec_helper.rb"
+ "Gemfile",
+ "MIT-LICENSE",
+ "README.rdoc",
+ "Rakefile",
+ "VERSION",
+ "generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb",
+ "generators/acts_as_taggable_on_migration/templates/migration.rb",
+ "lib/acts-as-taggable-on.rb",
+ "lib/acts_as_taggable_on/acts_as_taggable_on.rb",
+ "lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb",
+ "lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb",
+ "lib/acts_as_taggable_on/acts_as_taggable_on/core.rb",
+ "lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb",
+ "lib/acts_as_taggable_on/acts_as_taggable_on/related.rb",
+ "lib/acts_as_taggable_on/acts_as_tagger.rb",
+ "lib/acts_as_taggable_on/compatibility/Gemfile",
+ "lib/acts_as_taggable_on/compatibility/active_record_backports.rb",
+ "lib/acts_as_taggable_on/tag.rb",
+ "lib/acts_as_taggable_on/tag_list.rb",
+ "lib/acts_as_taggable_on/tagging.rb",
+ "lib/acts_as_taggable_on/tags_helper.rb",
+ "lib/generators/acts_as_taggable_on/migration/migration_generator.rb",
+ "lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb",
+ "rails/init.rb",
+ "spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb",
+ "spec/acts_as_taggable_on/acts_as_tagger_spec.rb",
+ "spec/acts_as_taggable_on/tag_list_spec.rb",
+ "spec/acts_as_taggable_on/tag_spec.rb",
+ "spec/acts_as_taggable_on/taggable_spec.rb",
+ "spec/acts_as_taggable_on/tagger_spec.rb",
+ "spec/acts_as_taggable_on/tagging_spec.rb",
+ "spec/acts_as_taggable_on/tags_helper_spec.rb",
+ "spec/bm.rb",
+ "spec/database.yml.sample",
+ "spec/models.rb",
+ "spec/schema.rb",
+ "spec/spec_helper.rb"
]
s.homepage = %q{http://github.com/mbleigh/acts-as-taggable-on}
- s.rdoc_options = ["--charset=UTF-8"]
s.require_paths = ["lib"]
- s.rubygems_version = %q{1.3.6}
+ s.rubygems_version = %q{1.5.3}
s.summary = %q{ActsAsTaggableOn is a tagging plugin for Rails that provides multiple tagging contexts on a single model.}
s.test_files = [
"spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb",
- "spec/acts_as_taggable_on/acts_as_tagger_spec.rb",
- "spec/acts_as_taggable_on/tag_list_spec.rb",
- "spec/acts_as_taggable_on/tag_spec.rb",
- "spec/acts_as_taggable_on/taggable_spec.rb",
- "spec/acts_as_taggable_on/tagger_spec.rb",
- "spec/acts_as_taggable_on/tagging_spec.rb",
- "spec/acts_as_taggable_on/tags_helper_spec.rb",
- "spec/bm.rb",
- "spec/models.rb",
- "spec/schema.rb",
- "spec/spec_helper.rb"
+ "spec/acts_as_taggable_on/acts_as_tagger_spec.rb",
+ "spec/acts_as_taggable_on/tag_list_spec.rb",
+ "spec/acts_as_taggable_on/tag_spec.rb",
+ "spec/acts_as_taggable_on/taggable_spec.rb",
+ "spec/acts_as_taggable_on/tagger_spec.rb",
+ "spec/acts_as_taggable_on/tagging_spec.rb",
+ "spec/acts_as_taggable_on/tags_helper_spec.rb",
+ "spec/bm.rb",
+ "spec/models.rb",
+ "spec/schema.rb",
+ "spec/spec_helper.rb"
]
if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ s.add_runtime_dependency(%q<rails>, [">= 3.0"])
else
+ s.add_dependency(%q<rails>, [">= 3.0"])
end
else
+ s.add_dependency(%q<rails>, [">= 3.0"])
end
end
View
26 lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
@@ -8,10 +8,10 @@ def self.included(base)
attr_writer :custom_contexts
after_save :save_tags
end
-
+
base.initialize_acts_as_taggable_on_core
end
-
+
module ClassMethods
def initialize_acts_as_taggable_on_core
tag_types.map(&:to_s).each do |tags_type|
@@ -38,14 +38,14 @@ def all_#{tags_type}_list
all_tags_list_on('#{tags_type}')
end
)
- end
+ end
end
-
+
def acts_as_taggable_on(*args)
super(*args)
initialize_acts_as_taggable_on_core
end
-
+
# all column names are necessary for PostgreSQL group clause
def grouped_column_names_for(object)
object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(", ")
@@ -76,11 +76,11 @@ def tagged_with(tags, options = {})
context = options.delete(:on)
if options.delete(:exclude)
- tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
+ tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", ActsAsTaggableOn::Tag.comparable_name(t)]) }.join(" OR ")
conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
elsif options.delete(:any)
- tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
+ tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", ActsAsTaggableOn::Tag.comparable_name(t)]) }.join(" OR ")
conditions << "#{table_name}.#{primary_key} IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
else
@@ -126,8 +126,8 @@ def tagged_with(tags, options = {})
def is_taggable?
true
end
- end
-
+ end
+
module InstanceMethods
# all column names are necessary for PostgreSQL group clause
def grouped_column_names_for(object)
@@ -180,7 +180,7 @@ def all_tags_on(context)
opts = ["#{tagging_table_name}.context = ?", context.to_s]
scope = base_tags.where(opts)
-
+
if ActsAsTaggableOn::Tag.using_postgresql?
group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
scope = scope.order("max(#{tagging_table_name}.created_at)").group(group_columns)
@@ -213,7 +213,7 @@ def reload(*args)
instance_variable_set("@#{context.to_s.singularize}_list", nil)
instance_variable_set("@all_#{context.to_s.singularize}_list", nil)
end
-
+
super(*args)
end
@@ -229,7 +229,7 @@ def save_tags
current_tags = tags_on(context)
old_tags = current_tags - tag_list
new_tags = tag_list - current_tags
-
+
# Find taggings to remove:
old_taggings = taggings.where(:tagger_type => nil, :tagger_id => nil,
:context => context.to_s, :tag_id => old_tags).all
@@ -249,4 +249,4 @@ def save_tags
end
end
end
-end
+end
View
33 lib/acts_as_taggable_on/tag.rb
@@ -1,7 +1,7 @@
module ActsAsTaggableOn
class Tag < ::ActiveRecord::Base
include ActsAsTaggableOn::ActiveRecord::Backports if ::ActiveRecord::VERSION::MAJOR < 3
-
+
attr_accessible :name
### ASSOCIATIONS:
@@ -14,30 +14,31 @@ class Tag < ::ActiveRecord::Base
validates_uniqueness_of :name
### SCOPES:
-
+
def self.using_postgresql?
connection.adapter_name == 'PostgreSQL'
end
def self.named(name)
- where(["name #{like_operator} ?", name])
+ where(["name = ?", comparable_name(name)])
end
-
+
def self.named_any(list)
- where(list.map { |tag| sanitize_sql(["name #{like_operator} ?", tag.to_s]) }.join(" OR "))
+ where(list.map { |tag| sanitize_sql(["name = ?", comparable_name(tag.to_s)]) }.join(" OR "))
end
-
+
def self.named_like(name)
- where(["name #{like_operator} ?", "%#{name}%"])
+ where(["name #{like_operator} ?", "%#{comparable_name(name)}%"])
end
def self.named_like_any(list)
- where(list.map { |tag| sanitize_sql(["name #{like_operator} ?", "%#{tag.to_s}%"]) }.join(" OR "))
+ where(list.map { |tag| sanitize_sql(["name #{like_operator} ?", "%#{comparable_name(tag.to_s)}%"]) }.join(" OR "))
end
### CLASS METHODS:
def self.find_or_create_with_like_by_name(name)
+ name = comparable_name(name)
named_like(name).first || create(:name => name)
end
@@ -47,7 +48,7 @@ def self.find_or_create_all_with_like_by_name(*list)
return [] if list.empty?
existing_tags = Tag.named_any(list).all
- new_tag_names = list.reject do |name|
+ new_tag_names = list.reject do |name|
name = comparable_name(name)
existing_tags.any? { |tag| comparable_name(tag.name) == name }
end
@@ -58,6 +59,10 @@ def self.find_or_create_all_with_like_by_name(*list)
### INSTANCE METHODS:
+ def name= new_name
+ write_attribute(:name, self.class.comparable_name(new_name))
+ end
+
def ==(object)
super || (object.is_a?(Tag) && name == object.name)
end
@@ -71,14 +76,14 @@ def count
end
class << self
+ def comparable_name(str)
+ RUBY_VERSION >= "1.9" ? str.downcase : str.mb_chars.downcase
+ end
+
private
def like_operator
using_postgresql? ? 'ILIKE' : 'LIKE'
end
-
- def comparable_name(str)
- RUBY_VERSION >= "1.9" ? str.downcase : str.mb_chars.downcase
- end
end
end
-end
+end
View
44 spec/acts_as_taggable_on/taggable_spec.rb
@@ -27,11 +27,11 @@
it "should be able to create tags" do
@taggable.skill_list = "ruby, rails, css"
@taggable.instance_variable_get("@skill_list").instance_of?(ActsAsTaggableOn::TagList).should be_true
-
+
lambda {
@taggable.save
}.should change(ActsAsTaggableOn::Tag, :count).by(3)
-
+
@taggable.reload
@taggable.skill_list.sort.should == %w(ruby rails css).sort
end
@@ -40,10 +40,10 @@
@taggable.tag_list_on(:test).add("hello")
@taggable.tag_list_cache_on(:test).should_not be_empty
@taggable.tag_list_on(:test).should == ["hello"]
-
+
@taggable.save
@taggable.save_tags
-
+
@taggable.reload
@taggable.tag_list_on(:test).should == ["hello"]
end
@@ -120,10 +120,10 @@
xit "should not return read-only records" do
# apparantly, there is no way to set readonly to false in a scope if joins are made
end
-
+
it "should be possible to return writable records" do
TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
- TaggableModel.tagged_with("ruby").first(:readonly => false).should_not be_readonly
+ TaggableModel.tagged_with("ruby").first(:readonly => false).should_not be_readonly
end
end
@@ -148,10 +148,10 @@
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby, java")
-
+
TaggableModel.tagged_with('rails').all_tag_counts.should have(3).items
TaggableModel.tagged_with('rails').all_tag_counts.any? { |tag| tag.name == 'java' }.should be_false
-
+
# Test specific join syntaxes:
frank.untaggable_models.create!
TaggableModel.tagged_with('rails').scoped(:joins => :untaggable_models).all_tag_counts.should have(2).items
@@ -177,15 +177,15 @@
TaggableModel.tagged_with("ruby, rails", :order => 'taggable_models.name').to_a.should == [bob, frank]
TaggableModel.tagged_with(["ruby", "rails"], :order => 'taggable_models.name').to_a.should == [bob, frank]
end
-
+
it "should be able to find tagged with quotation marks" do
bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive, 'I love the ,comma,'")
TaggableModel.tagged_with("'I love the ,comma,'").should include(bob)
end
-
+
it "should be able to find tagged with invalid tags" do
- bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive")
- TaggableModel.tagged_with("sad, happier").should_not include(bob)
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive")
+ TaggableModel.tagged_with("sad, happier").should_not include(bob)
end
it "should be able to find tagged with any tag" do
@@ -243,12 +243,12 @@
bob.save
}.should change(ActsAsTaggableOn::Tagging, :count).by(1)
end
-
+
describe "Associations" do
before(:each) do
@taggable = TaggableModel.create(:tag_list => "awesome, epic")
end
-
+
it "should not remove tags when creating associated objects" do
@taggable.untaggable_models.create!
@taggable.reload
@@ -272,44 +272,44 @@
@inherited_same = InheritingTaggableModel.new(:name => "inherited same")
@inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
end
-
+
it "should be able to save tags for inherited models" do
@inherited_same.tag_list = "bob, kelso"
@inherited_same.save
InheritingTaggableModel.tagged_with("bob").first.should == @inherited_same
end
-
+
it "should find STI tagged models on the superclass" do
@inherited_same.tag_list = "bob, kelso"
@inherited_same.save
TaggableModel.tagged_with("bob").first.should == @inherited_same
end
-
+
it "should be able to add on contexts only to some subclasses" do
@inherited_different.part_list = "fork, spoon"
@inherited_different.save
InheritingTaggableModel.tagged_with("fork", :on => :parts).should be_empty
AlteredInheritingTaggableModel.tagged_with("fork", :on => :parts).first.should == @inherited_different
end
-
+
it "should have different tag_counts_on for inherited models" do
@inherited_same.tag_list = "bob, kelso"
@inherited_same.save!
@inherited_different.tag_list = "fork, spoon"
@inherited_different.save!
-
+
InheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso)
AlteredInheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(fork spoon)
TaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso fork spoon)
end
-
+
it 'should store same tag without validation conflict' do
@taggable.tag_list = 'one'
@taggable.save!
-
+
@inherited_same.tag_list = 'one'
@inherited_same.save!
-
+
@inherited_same.update_attributes! :name => 'foo'
end
end
View
12 spec/spec_helper.rb
@@ -13,7 +13,7 @@
Bundler.setup
rescue Bundler::GemNotFound
raise RuntimeError, "Bundler couldn't find some gems." +
- "Did you run \`bundlee install\`?"
+ "Did you run \`bundle install\`?"
end
Bundler.require
@@ -34,17 +34,17 @@ def freq
database_yml = File.expand_path('../database.yml', __FILE__)
if File.exists?(database_yml)
active_record_configuration = YAML.load_file(database_yml)[ENV['DB']]
-
+
ActiveRecord::Base.establish_connection(active_record_configuration)
ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
-
+
ActiveRecord::Base.silence do
ActiveRecord::Migration.verbose = false
-
+
load(File.dirname(__FILE__) + '/schema.rb')
load(File.dirname(__FILE__) + '/models.rb')
- end
-
+ end
+
else
raise "Please create #{database_yml} first to configure your database. Take a look at: #{database_yml}.sample"
end

No commit comments for this range

Something went wrong with that request. Please try again.