redis_tags 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|