redis_tags 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +2 -2
- data/lib/redis_tags/{tag.rb → redis_tag.rb} +17 -11
- data/lib/redis_tags/{tag_list.rb → redis_tag_list.rb} +13 -7
- data/lib/redis_tags/version.rb +1 -1
- data/lib/redis_tags.rb +11 -17
- data/spec/models/book.rb +12 -2
- data/spec/spec/{tag_spec.rb → redis_tag_spec.rb} +9 -10
- data/spec/spec/redis_tags_spec.rb +5 -5
- metadata +8 -8
data/README.md
CHANGED
@@ -60,8 +60,8 @@ Or install it yourself as:
|
|
60
60
|
@user.tag_collection = ["beata"] # => ["beata"]
|
61
61
|
@user.save
|
62
62
|
|
63
|
-
User.
|
64
|
-
User.
|
63
|
+
User.has_tags(:tags => ["elad"]) # => [@user.id]
|
64
|
+
User.tags_starting_with("el") # => ["elad"]
|
65
65
|
|
66
66
|
## Contributing
|
67
67
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RedisTags
|
2
|
-
class
|
2
|
+
class RedisTag
|
3
3
|
attr_accessor :name
|
4
4
|
attr_reader :owner_class
|
5
5
|
|
@@ -24,27 +24,32 @@ module RedisTags
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def count
|
27
|
-
engine.
|
27
|
+
engine.zcard redis_key
|
28
28
|
end
|
29
29
|
|
30
|
-
def self.
|
31
|
-
#debugger
|
30
|
+
def self.has_tags(klass, options = {})
|
32
31
|
key_array = []
|
33
32
|
if options[:tags].to_a.size == 1
|
34
33
|
if options[:random].to_i > 0
|
35
|
-
klass.redis_tags_engine.
|
34
|
+
klass.redis_tags_engine.zrandmember RedisTags::RedisTag.tagged_with_key_for(klass, options[:tags]), options[:random].to_i
|
35
|
+
elsif options[:since]
|
36
|
+
klass.redis_tags_engine.zrangebyscore RedisTags::RedisTag.tagged_with_key_for(klass, options[:tags]), options[:since].to_i, Time.now.to_i
|
36
37
|
else
|
37
|
-
klass.redis_tags_engine.
|
38
|
+
klass.redis_tags_engine.zrangebyscore RedisTags::RedisTag.tagged_with_key_for(klass, options[:tags]), Time.now.to_i - 7 * 60 * 60 * 24, Time.now.to_i
|
38
39
|
end
|
39
40
|
else
|
40
41
|
options[:tags].to_a.each do |tag_name|
|
41
|
-
key_array <<
|
42
|
+
key_array << RedisTag.tagged_with_key_for(klass, tag_name)
|
42
43
|
end
|
43
|
-
|
44
|
+
|
45
|
+
klass.redis_tags_engine.zinterstore RedisTags::RedisTag.intersect_key_for(klass, options[:tags]), key_array, {:aggregate => :max}
|
46
|
+
|
44
47
|
if options[:random].to_i > 0
|
45
|
-
klass.redis_tags_engine.
|
48
|
+
klass.redis_tags_engine.zrandmember RedisTags::RedisTag.intersect_key_for(klass, options[:tags]), options[:random].to_i
|
49
|
+
elsif options[:since]
|
50
|
+
klass.redis_tags_engine.zrangebyscore RedisTags::RedisTag.intersect_key_for(klass, options[:tags]), options[:since].to_i, Time.now.to_i
|
46
51
|
else
|
47
|
-
klass.redis_tags_engine.
|
52
|
+
klass.redis_tags_engine.zrangebyscore RedisTags::RedisTag.intersect_key_for(klass, options[:tags]), (Time.now.to_i - 7 * 60 * 60 * 24), Time.now.to_i
|
48
53
|
end
|
49
54
|
end
|
50
55
|
end
|
@@ -66,4 +71,5 @@ module RedisTags
|
|
66
71
|
def redis_key
|
67
72
|
"#{self.owner_class}:tagged_with:#{self.name.downcase.gsub(" ", '-')}"
|
68
73
|
end
|
69
|
-
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,14 +1,20 @@
|
|
1
1
|
module RedisTags
|
2
|
-
class
|
2
|
+
class RedisTagList < Array
|
3
3
|
|
4
4
|
attr_reader :owner, :owner_class, :owner_id, :tags
|
5
5
|
|
6
|
-
def initialize(owner)
|
6
|
+
def initialize(owner, tags = nil)
|
7
7
|
@owner = owner
|
8
8
|
@owner_class = owner.class.to_s.downcase
|
9
9
|
@owner_id = owner.id
|
10
|
-
|
11
|
-
|
10
|
+
if tags.nil? && !(owner.id.nil?)
|
11
|
+
super(engine.smembers(self.redis_key))
|
12
|
+
else
|
13
|
+
if tags.nil?
|
14
|
+
tags = []
|
15
|
+
end
|
16
|
+
append_multi(tags)
|
17
|
+
end
|
12
18
|
end
|
13
19
|
|
14
20
|
def <<(tag_name)
|
@@ -16,10 +22,10 @@ module RedisTags
|
|
16
22
|
if !(self.owner_id.nil?)
|
17
23
|
engine.multi do
|
18
24
|
engine.sadd self.redis_key, tag_name
|
19
|
-
engine.
|
25
|
+
engine.zadd "#{self.owner_class}:tagged_with:#{tag_name.gsub(" ", '-')}", @owner.created_at.to_i.to_s, self.owner_id
|
20
26
|
end
|
21
27
|
engine.multi do
|
22
|
-
RedisTags::
|
28
|
+
RedisTags::RedisTag.register_tag_for_autocomplete(engine, tag_name)
|
23
29
|
end
|
24
30
|
end
|
25
31
|
super(tag_name)
|
@@ -30,7 +36,7 @@ module RedisTags
|
|
30
36
|
if !(self.owner_id.nil?)
|
31
37
|
engine.multi do
|
32
38
|
engine.srem self.redis_key, tag_name
|
33
|
-
engine.
|
39
|
+
engine.zrem "#{self.owner_class}:tagged_with:#{tag_name.gsub(" ", '-')}", self.owner_id
|
34
40
|
end
|
35
41
|
end
|
36
42
|
super(tag_name)
|
data/lib/redis_tags/version.rb
CHANGED
data/lib/redis_tags.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "redis_tags/version"
|
2
|
-
require "redis_tags/
|
3
|
-
require "redis_tags/
|
2
|
+
require "redis_tags/redis_tag"
|
3
|
+
require "redis_tags/redis_tag_list"
|
4
4
|
|
5
5
|
module RedisTags
|
6
6
|
|
@@ -37,45 +37,39 @@ module RedisTags
|
|
37
37
|
@@redis_tags_engine
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
|
40
|
+
def has_tags(options = {})
|
41
|
+
RedisTags::RedisTag.has_tags(self, options)
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
45
|
-
RedisTags::
|
44
|
+
def tags_starting_with(partial_tag_name)
|
45
|
+
RedisTags::RedisTag.starts_with?(self.redis_tags_engine, partial_tag_name)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
module InstanceMethods
|
50
50
|
|
51
|
-
def
|
51
|
+
def tags_collection
|
52
52
|
if self.class.acts_as_taggable_on_steroids_legacy_mode?
|
53
|
-
|
54
|
-
tags_collection = legacy_tag_list
|
55
|
-
legacy_tag_list
|
53
|
+
@_tag_list ||= RedisTags::RedisTagList.new(self, self.tag_list)
|
56
54
|
else
|
57
|
-
|
55
|
+
@_tag_list ||= RedisTags::RedisTagList.new(self)
|
58
56
|
end
|
59
57
|
end
|
60
58
|
|
61
|
-
def tags_collection
|
62
|
-
@tag_list ||= RedisTags::TagList.new(self)
|
63
|
-
end
|
64
|
-
|
65
59
|
def tag_with(tag)
|
66
60
|
tags_collection << tag
|
67
61
|
end
|
68
62
|
|
69
63
|
def tags_collection=(new_tag_list)
|
70
64
|
tags_collection.delete_all
|
71
|
-
@
|
65
|
+
@_tag_list = RedisTags::RedisTagList.new(self, new_tag_list)
|
72
66
|
end
|
73
67
|
|
74
68
|
private
|
75
69
|
|
76
70
|
# After save callback, confirms that redis is saved after object exists.
|
77
71
|
def update_tags_to_redis
|
78
|
-
tags_collection = @
|
72
|
+
tags_collection = RedisTags::RedisTagList.new(self, @_tag_list)
|
79
73
|
end
|
80
74
|
end
|
81
75
|
end
|
data/spec/models/book.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
class Book
|
2
|
+
|
3
|
+
attr_accessor :id
|
4
|
+
attr_reader :created_at
|
5
|
+
attr_accessor :tag_list
|
6
|
+
def Book.after_save(arg)
|
7
|
+
|
8
|
+
end
|
9
|
+
|
2
10
|
include RedisTags
|
3
11
|
|
4
12
|
uses_redis_tags
|
5
13
|
|
6
|
-
def
|
14
|
+
def initialize(tag_list = [])
|
7
15
|
@id = nil
|
16
|
+
@created_at = Time.now
|
17
|
+
@tag_list = tag_list
|
8
18
|
end
|
9
19
|
|
10
20
|
def id
|
@@ -12,7 +22,7 @@ class Book
|
|
12
22
|
end
|
13
23
|
|
14
24
|
def save
|
15
|
-
|
25
|
+
self.id = rand(1000)
|
16
26
|
after_save
|
17
27
|
end
|
18
28
|
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe RedisTags::RedisTag do
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
Book.redis_tags_engine.flushdb
|
7
7
|
end
|
8
8
|
|
9
|
-
it "should initialize a new
|
9
|
+
it "should initialize a new RedisTag instance" do
|
10
10
|
@b = Book.new
|
11
|
-
@t =
|
11
|
+
@t = RedisTags::RedisTag.new(@b, "koksi")
|
12
12
|
@t.name.should == "koksi"
|
13
13
|
@t.owner_class.should == "book"
|
14
14
|
|
@@ -18,14 +18,13 @@ describe Tag do
|
|
18
18
|
it "should intersect more than 1 tag" do
|
19
19
|
@book1 = Book.new
|
20
20
|
@book2 = Book.new
|
21
|
-
#debugger
|
22
21
|
@book1.tags_collection = "elad, deddy, erez"
|
23
|
-
|
24
22
|
@book1.save
|
23
|
+
|
25
24
|
@book2.tags_collection = "elad, deddy"
|
26
25
|
@book2.save
|
27
26
|
|
28
|
-
[@book1.id, @book2.id].should =~
|
27
|
+
[@book1.id, @book2.id].should =~ RedisTags::RedisTag.has_tags(Book, {:tags => ["elad", "deddy"]}).collect(&:to_i)
|
29
28
|
end
|
30
29
|
|
31
30
|
it "should intersect 1 tag" do
|
@@ -37,15 +36,15 @@ describe Tag do
|
|
37
36
|
@book2.tags_collection = "elad, deddy"
|
38
37
|
@book2.save
|
39
38
|
|
40
|
-
[@book1.id, @book2.id].should =~
|
39
|
+
[@book1.id, @book2.id].should =~ RedisTags::RedisTag.has_tags(Book, {:tags => ["elad"]}).collect(&:to_i)
|
41
40
|
end
|
42
41
|
|
43
42
|
it "should log autocomplete options for each tag" do
|
44
43
|
@book = Book.new
|
45
44
|
@book.tags_collection = "elad", "eli", "eliran hamelech shel ramle"
|
46
45
|
@book.save
|
47
|
-
Book.
|
48
|
-
Book.
|
49
|
-
Book.
|
46
|
+
Book.tags_starting_with("el").should =~ ["elad", "eli", "eliran hamelech shel ramle"]
|
47
|
+
Book.tags_starting_with("ela").should =~ ["elad"]
|
48
|
+
Book.tags_starting_with("eli").should =~ ["eli", "eliran hamelech shel ramle"]
|
50
49
|
end
|
51
50
|
end
|
@@ -9,18 +9,21 @@ describe RedisTags do
|
|
9
9
|
it "should create multiple tags" do
|
10
10
|
@book = Book.new
|
11
11
|
@book.tags_collection = "elad, koko, loko"
|
12
|
+
@book.save
|
12
13
|
@book.tags_collection.should eql(["elad", "koko", "loko"])
|
13
14
|
end
|
14
15
|
|
15
16
|
it "should save a new tag using <<" do
|
16
17
|
@book = Book.new
|
17
18
|
@book.tag_with "elad"
|
19
|
+
@book.save
|
18
20
|
@book.tags_collection.should eql(["elad"])
|
19
21
|
end
|
20
22
|
|
21
23
|
it "should save a new tag downcased" do
|
22
24
|
@book = Book.new
|
23
25
|
@book.tag_with "ELAD"
|
26
|
+
@book.save
|
24
27
|
@book.tags_collection.should eql(["elad"])
|
25
28
|
end
|
26
29
|
|
@@ -32,7 +35,7 @@ describe RedisTags do
|
|
32
35
|
@book = Book.new
|
33
36
|
lambda {
|
34
37
|
@book.tag_list
|
35
|
-
}.
|
38
|
+
}.should_not raise_error(NoMethodError)
|
36
39
|
end
|
37
40
|
|
38
41
|
it "should update Redis tags collection with backward compatibility for acts_as_taggable_on_steroids (#tag_list)" do
|
@@ -40,10 +43,7 @@ describe RedisTags do
|
|
40
43
|
uses_redis_tags :acts_as_taggable_on_steroids_legacy_mode => true
|
41
44
|
end
|
42
45
|
|
43
|
-
@book = Book.new
|
44
|
-
lambda {
|
45
|
-
@book.tag_list
|
46
|
-
}.should raise_error(NoMethodError)
|
46
|
+
@book = Book.new([])
|
47
47
|
|
48
48
|
@book.tags_collection.should eql([])
|
49
49
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_tags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Elad Meidar
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-11-
|
18
|
+
date: 2012-11-08 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -79,13 +79,13 @@ files:
|
|
79
79
|
- README.md
|
80
80
|
- Rakefile
|
81
81
|
- lib/redis_tags.rb
|
82
|
-
- lib/redis_tags/
|
83
|
-
- lib/redis_tags/
|
82
|
+
- lib/redis_tags/redis_tag.rb
|
83
|
+
- lib/redis_tags/redis_tag_list.rb
|
84
84
|
- lib/redis_tags/version.rb
|
85
85
|
- redis_tags.gemspec
|
86
86
|
- spec/models/book.rb
|
87
|
+
- spec/spec/redis_tag_spec.rb
|
87
88
|
- spec/spec/redis_tags_spec.rb
|
88
|
-
- spec/spec/tag_spec.rb
|
89
89
|
- spec/spec_helper.rb
|
90
90
|
has_rdoc: true
|
91
91
|
homepage: ""
|
@@ -123,6 +123,6 @@ specification_version: 3
|
|
123
123
|
summary: This implementation consists over 3 basic rules. keep who is tagged, keep what is tagged and keep all tags.
|
124
124
|
test_files:
|
125
125
|
- spec/models/book.rb
|
126
|
+
- spec/spec/redis_tag_spec.rb
|
126
127
|
- spec/spec/redis_tags_spec.rb
|
127
|
-
- spec/spec/tag_spec.rb
|
128
128
|
- spec/spec_helper.rb
|