Skip to content

Commit

Permalink
Added README docs, as well as uniqueness to the list
Browse files Browse the repository at this point in the history
  • Loading branch information
markbates committed Sep 21, 2012
1 parent 4893495 commit ebcf956
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 16 deletions.
74 changes: 68 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Mongoid::Tags::Arent::Hard
# Mongoid::TagsArentHard

TODO: Write a gem description
A tagging gem for Mongoid 3 that doesn't actually suck.

For some reason all of the tagging gems for Mongoid suck. Not sure why, it's really not that hard a problem to solve. One of the biggest complaints I have is that you can't have a model that has two types of "tags". The other problem I have with the other gems is that I want to be able to set my tags equal to a string and have it become an Array, and vice versa. This gem solves both of those problems.

## Installation

Expand All @@ -18,12 +20,72 @@ Or install it yourself as:

## Usage

TODO: Write usage instructions here
To add tags to a model you need to first include the <code>Mongoid::TagsArentHard</code> module and then define what you want the field to be called using the <code>taggable_with</code> method.

<pre><code>
class Foo
include Mongoid::Document
include Mongoid::TagsArentHard

taggable_with :tags
taggable_with :colors, separator: ";"
end
</code></pre>

Now we have two different types of "tags"; the first being called <code>tags</code> and the second being called <code>colors</code>. We have also told the <code>colors</code> to use <code>";"</code> as its separator.

Now we can do fun things like this:

<pre><code>
# set with either a string or an array:
foo = Foo.new(tags: "a,b,c", colors: ["red", "blue"])

# retrieve the list:
foo.tags #=> ["a", "b", "c"]
foo.colors #=> ["red", "blue"]

# append with either a string or an array:
foo.tags << "d"
foo.tags #=> ["a", "b", "c", "d"]
foo.colors << ["green", "yellow"]
foo.colors #=> ["red", "blue", "green", "yellow"]

# set with either a string or an array:
foo.tags = ["x", "y", "z"]
foo.tags #=> ["x", "y", "z"]
foo.colors = "black;brown"
foo.colors #=> ["black", "brown"]
</code></pre>

### Searching

There are a few scopes included that make it easy to find objects that have the tags you are looking for. These methods are generated using the name of the field you designed, so in our previous example we would have the following methods available to us:

<pre><code>
# Find objects with any of the values:
Foo.with_any_tags("a")
Foo.with_any_tags(["a", "b"])
Foo.with_any_tags("a, b")
Foo.with_any_colors("a")
Foo.with_any_colors(["a", "b"])
Foo.with_any_colors("a, b")

# Find objects with all of these values:
Foo.with_all_tags("a")
Foo.with_all_tags(["a", "b"])
Foo.with_all_tags("a, b")
Foo.with_all_colors("a")
Foo.with_all_colors(["a", "b"])
Foo.with_all_colors("a, b")
</code></pre>

Again, notice that you can use either a string, an array, or a splatted list as values to these scopes.

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
3. Write your tests
4. Commit your changes (`git commit -am 'Add some feature'`)
5. Push to the branch (`git push origin my-new-feature`)
6. Create new Pull Request
12 changes: 10 additions & 2 deletions lib/mongoid/tags_arent_hard/tags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@ class Tags

attr_accessor :tag_list
attr_accessor :options
delegate :<<, :join, :map, :each, :inspect, :==, :===, :eql?, :__bson_dump__, to: :tag_list
delegate :join, :map, :each, :inspect, :==, :===, :eql?, :__bson_dump__, to: :tag_list

def initialize(*tag_list, options)
self.options = {separator: Mongoid::TagsArentHard.config.separator}.merge(options)
self.tag_list = self.normalize(*tag_list)
self.tag_list = []
self.<<(*tag_list)
end

def normalize(*tag_list)
tag_list.flatten.map {|s| s.split(self.options[:separator]).map {|x| x.strip}}.flatten
end

def <<(*tag_list)
self.tag_list << self.normalize(*tag_list)
self.tag_list.flatten!
self.tag_list.uniq!
return self.tag_list
end

def to_s
self.join(self.options[:separator])
end
Expand Down
2 changes: 1 addition & 1 deletion lib/mongoid/tags_arent_hard/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Mongoid
module Tags
module Arent
module Hard
VERSION = "0.0.1"
VERSION = "1.0.0"
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions mongoid-tags-arent-hard.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
gem.version = Mongoid::Tags::Arent::Hard::VERSION
gem.authors = ["Mark Bates"]
gem.email = ["mark@markbates.com"]
gem.description = %q{TODO: Write a gem description}
gem.summary = %q{TODO: Write a gem summary}
gem.description = %q{A tagging gem for Mongoid 3 that doesn't actually suck.}
gem.summary = %q{A tagging gem for Mongoid 3 that doesn't actually suck.}
gem.homepage = ""

gem.files = `git ls-files`.split($/)
Expand Down
7 changes: 6 additions & 1 deletion spec/tags_arent_hard/tags_arent_hard_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ class Foo
foo.send(_name).should eql([])
end

it "defines a setter for '#{_name}'" do
it "defines a setter for '#{_name}' (string)" do
foo.send("#{_name}=", "foo #{_separator} bar")
foo.send(_name).should eql(["foo","bar"])
end

it "defines a setter for '#{_name}' (array)" do
foo.send("#{_name}=", ["foo", "bar"])
foo.send(_name).should eql(["foo","bar"])
end

end

Expand Down
30 changes: 26 additions & 4 deletions spec/tags_arent_hard/tags_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,44 @@

it "takes an array of tags" do
tags = Mongoid::TagsArentHard::Tags.new(["foo", "bar"], {})
tags.tag_list.should eql(["foo", "bar"])
tags.should eql(["foo", "bar"])
end

it "takes a splatted list" do
tags = Mongoid::TagsArentHard::Tags.new("foo", "bar", {})
tags.tag_list.should eql(["foo", "bar"])
tags.should eql(["foo", "bar"])
end

it "takes a string" do
tags = Mongoid::TagsArentHard::Tags.new("foo,bar", {})
tags.tag_list.should eql(["foo", "bar"])
tags.should eql(["foo", "bar"])
end

it "takes a string with a different separator" do
tags = Mongoid::TagsArentHard::Tags.new("foo bar", separator: " ")
tags.tag_list.should eql(["foo", "bar"])
tags.should eql(["foo", "bar"])
end

end

describe '<<' do

it "takes a string" do
tags << "fubar"
tags.should eql(["foo", "bar", "baz", "fubar"])

tags << "a,b"
tags.should eql(["foo", "bar", "baz", "fubar", "a", "b"])
end

it "takes an array" do
tags << ["a", "b"]
tags.should eql(["foo", "bar", "baz", "a", "b"])
end

it "should not allow duplicates" do
tags << "foo"
tags.should eql(["foo", "bar", "baz"])
end

end
Expand Down

0 comments on commit ebcf956

Please sign in to comment.